[patch 3/4] drm/qxl: array underflow in qxl_clientcap_ioctl()

2015-09-17 Thread Dan Carpenter
> Actually there is no underflow.

Oh, duh.  You're right.  Sorry for that.

regards,
dan carpenter



[Bug 104551] Unable to resume from suspend AMD Radeon HD 6570

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

--- Comment #2 from Michel Dänzer  ---
The attached log looks to be from running Catalyst/fglrx. Please attach the log
and dmesg from running the radeon driver.

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


[PATCH RFC 1/8] dt-bindings: Document the hi6220 bindings for DRM driver

2015-09-17 Thread Xinwei Kong
hi architt

On 2015/9/16 17:10, Archit Taneja wrote:
> Hi,
> 
> On 09/16/2015 02:04 PM, Xinwei Kong wrote:
>> hi architt
>>
>> On 2015/9/16 2:11, Rob Herring wrote:
>>> On 09/15/2015 04:37 AM, Xinwei Kong wrote:
 This adds documentation of device tree bindings for the
 Graphics Processing Unit of hi6220 SOC.

 Signed-off-by: Xinliang Liu 
 Signed-off-by: Xinwei Kong 
 Signed-off-by: Andy Green 
 Signed-off-by: Jiwen Qi 
 Signed-off-by: Yu Gong 
 ---
   .../devicetree/bindings/gpu/hisilicon,hi6220.txt   | 69 
 ++
   1 file changed, 69 insertions(+)
   create mode 100644 
 Documentation/devicetree/bindings/gpu/hisilicon,hi6220.txt

 diff --git a/Documentation/devicetree/bindings/gpu/hisilicon,hi6220.txt 
 b/Documentation/devicetree/bindings/gpu/hisilicon,hi6220.txt
 new file mode 100644
 index 000..173ac63
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/gpu/hisilicon,hi6220.txt
 @@ -0,0 +1,69 @@
 + * Hisilicon hi6220 Graphics Processing Unit for HiKey board
 +
 + ** display-subsystem: Master device for binding DRM sub-components
>>>
>>> DRM is a Linuxism that doesn't belong in the binding.
>>>
 +This master device is parent node and it will be responsible to bind 
 all
 +sub-components devices node.
>>>
>>> Are these nodes a single block in the h/w? If not, you should describe
>>> the connection of sub-nodes with of-graph instead.
>>>
 +- Required properties :
 +  - compatible: "hisilicon,display-subsystem".
 +  - #address-cells, #size-cells: Must be present if the device has 
 sub-nodes.
 +  - ranges: to allow probing of subdevices.
 +  - dma-coherent: Present if dma operations are coherent.
 +
 + ** ade: Graphic overlay, Graphic post-processing, display timing control.
 +This device is child node of display-subsystem
 +- Required properties :
 +  - compatible: "hisilicon,hi6220-ade".
 +  - reg: physical base address of the ADE register and length of 
 memory
 +region.
 +  - reg-names: Should contain the reg names "ade_base" and 
 "media_base".
 +  - interrupt: The interrupt number to the cpu. Defines the interrupt
 +by ADE.
 +  - clocks: The clocks needed by the ADE module.
 +  - clock-names: the name of the clocks.
 +
 + ** dsi: support mipi dsi interface
 +This device is child node of display-subsystem
 +- Required properties :
 +  - compatible: "hisilicon,hi6220-dsi".
 +  - reg: physical base address of the DSI register and length of 
 memory
 +region.
 +  - clocks: The clocks needed by the DSI module.
 +  - clock-names: the name of the clocks.
 +  -encoder-slave: phandles to a 'encoder-slave' subnode which DSI 
 connect
 +ADV7533 in order to support hdmi display.
>>>
>>> What the ADV7533 binding looks like is still being discussed.
>>> "encoder-slave" is certainly DRM specific and not how it should be done.
>>> Most likely, this needs to use the of-graph ports.
>>>
>> I dont how to implement the encoder bridge stuff in upstream,
>> you think that I will how to handle this part?
> 
> You can use of-graph ports to link the dsi output with the adv7533
> bridge.
> 
> An example of the binding looks like:
> 
> Documentation/devicetree/bindings/drm/msm/dsi.txt
> 
> The implementation of this on the dsi host side of drm/msm
> can be found in dsi_host_parse_dt, in:
> 
> drivers/gpu/drm/msm/dsi/dsi_host.c
> 
> You can get to know more about of-graph parsing here:
> 
> Documentation/devicetree/bindings/graph.txt
> 
I study your patch about of-graph parsing, I know that how to parse this
dts endpoint node. Then i dont kow how to use this device_node (which is
get by "of_graph_get_remote_port_parent" function.) to hook adv7533 operation.

can you give me some help to how to use the adv7533 interface by device_node or
other way to use adv7533?

> I'd started going through the drm/hisil patches. I'll
> share more comments there.
> 
> Thanks,
> Archit
> 
>>
>> Thank you
>> xinwei
>>
>>> Also, the ADV7533 connection is specific to HiKey. This binding should
>>> just generically describe how any bridge or panel is connected.
>>>
>>> Rob
>>>
>>> .
>>>
>>
>> -- 
>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
> 



[PATCH RFC 6/8] drm: hisilicon: Add support for fbdev

2015-09-17 Thread Xinliang Liu
On 17 September 2015 at 19:52, Rob Clark  wrote:

> On Wed, Sep 16, 2015 at 5:48 AM, Xinliang Liu 
> wrote:
> >
> >
> > On 16 September 2015 at 02:25, Rob Herring  wrote:
> > Hi Rob, thanks a lot for reply:-)
> >
> >> On 09/15/2015 04:37 AM, Xinwei Kong wrote:
> >> > If you config DRM_HISI_FBDEV optional, this patch will only support
> >> > fbdev
> >> > mode while also supporting double buffer.
> >>
> >> This is a lot of duplicated code from CMA fbdev. Is double buffering the
> >> only reason why CMA fbdev can't be used or are there some other
> >> constraints?
> >
> > Yes, double buffering is the main reason we rewrite our own fbdev.
> > CMA fbdev only create one buffer. But we need at least  double buffer for
> > running Android with fbdev.
> >
> >> Double buffering in fbdev has always been a hack, so I'm
> >> guessing that is not a feature that should be added here.
> >>
> > If so, I think it is hard to be accepted for my cma fbdev patch to
> support
> > multi buffer.
> > This early week, I have sent a cma fbdev patch for supporting this. The
> > subject is
> > "[PATCH] drm/cma-helper: Add multi buffer support for cma fbdev".
> > We do have a strong will to support this feature. I described the reason
> in
> > the patch. Please take a look for me. Thank you very much.
>
> fwiw, drm_gralloc has support for kms.

We do have a plan to replace fbdev with kms. But it take time.


> Currently it is expected to be
> paired w/ a mesa gpu driver, which might not work for everyone, but I
> suppose the display part of it could be extracted out for a
> gralloc.kms.so for pure sw rendering.. that might be a better
> approach.
>

Yes, I also think kms should be handle in hwc rather than in gralloc.
IMO, gralloc should just handle dma buffer alloc and free.
We have a reference hwc implementation. which will handle kms inside it.
wiki:
https://wiki.linaro.org/BenjaminGaignard/HWComposer_DRM?highlight=%28hwcomposer%2
source code: git://git.linaro.org/people/benjamin.gaignard/hwcomposer.git

Cheers,
-Xinliang


> http://git.android-x86.org/?p=platform/hardware/drm_gralloc.git
>
> BR,
> -R
>
> > -Xinliang
> >
> >> Rob
> >>
> >> > Signed-off-by: Xinliang Liu 
> >> > Signed-off-by: Xinwei Kong 
> >> > Signed-off-by: Andy Green 
> >> > Signed-off-by: Jiwen Qi 
> >> > Signed-off-by: Yu Gong 
> >> > ---
> >> >  drivers/gpu/drm/hisilicon/Kconfig  |  13 +
> >> >  drivers/gpu/drm/hisilicon/Makefile |   3 +-
> >> >  drivers/gpu/drm/hisilicon/hisi_drm_connector.c |   4 +
> >> >  drivers/gpu/drm/hisilicon/hisi_drm_drv.c   |   9 +
> >> >  drivers/gpu/drm/hisilicon/hisi_drm_dsi.c   |  15 +
> >> >  drivers/gpu/drm/hisilicon/hisi_drm_fb.h|   5 +
> >> >  drivers/gpu/drm/hisilicon/hisi_drm_fbdev.c | 395
> >> > +
> >> >  drivers/gpu/drm/hisilicon/hisi_drm_fbdev.h |  24 ++
> >> >  8 files changed, 467 insertions(+), 1 deletion(-)
> >> >  create mode 100644 drivers/gpu/drm/hisilicon/hisi_drm_fbdev.c
> >> >  create mode 100644 drivers/gpu/drm/hisilicon/hisi_drm_fbdev.h
> >>
> >
> >
> > ___
> > dri-devel mailing list
> > dri-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/dri-devel
> >
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150917/92ec451c/attachment-0001.html>


[PATCH 01/15] vga_switcheroo: Document _ALL_ the things!

2015-09-17 Thread Lukas Wunner
Hi Danilo,

On Thu, Sep 17, 2015 at 01:34:54PM -0300, Danilo Cesar Lemes de Paula wrote:
> > - * GPU driver interface
> > - * - set_gpu_state - this should do the equiv of s/r for the card
> > - * - this should *not* set the discrete power state
> 
> Did you check if this creates the desired format? (ie: Doesn't create a
>  block).

These lines are deleted by the patch.

One oddity I did notice however is that in the HTML documentation for the
public function vga_switcheroo_process_delayed_switch(), instead of the
heading "Description" it says "Manual switching and manual power control"
(which is the identifier of the preceding DOC section). I guess it's a bug
in kernel-doc but I couldn't be bothered so far to look into it. No idea
if it's introduced by your patches or if it was there all along.

Another thing I noticed is that URLs are not clickable in the HTML output.

Otherwise the markdown support works great (though I've only used it for
unsorted lists in this documentation).

Thanks,

Lukas


[PATCH 03/15] vga_switcheroo: Set active attribute to false for audio clients

2015-09-17 Thread Lukas Wunner
After sending the below patch away I realized that this change allows
us to simplify the code a bit by dropping the client_is_vga() call
from find_active_client().

I force-pushed an amended version of the commit to my vga_switcheroo_docs
branch on GitHub:
https://github.com/l1k/linux/commit/85dc1f299dec5a52266d82e2f4c02adfb04f77e6


On Thu, Aug 27, 2015 at 04:43:43PM +0200, Lukas Wunner wrote:
> The active attribute in struct vga_switcheroo_client denotes whether
> the outputs are currently switched to this client. The attribute is
> only meaningful for vga clients. It is never used for audio clients.
> 
> The function vga_switcheroo_register_audio_client() misuses this
> attribute to store whether the audio device is fully initialized.
> Most likely there was a misunderstanding about the meaning of
> "active" when this was added.
> 
> Set the active attribute to false for audio clients. Remove the
> active parameter from vga_switcheroo_register_audio_client() and
> its sole caller, hda_intel.c:register_vga_switcheroo().
> 
> vga_switcheroo_register_audio_client() was introduced by 3e9e63dbd374
> ("vga_switcheroo: Add the support for audio clients"). Its use in
> hda_intel.c was introduced by a82d51ed24bb ("ALSA: hda - Support
> VGA-switcheroo").
> 
> Cc: Takashi Iwai 
> Signed-off-by: Lukas Wunner 
> ---
>  drivers/gpu/vga/vga_switcheroo.c | 5 ++---
>  include/linux/vga_switcheroo.h   | 4 ++--
>  sound/pci/hda/hda_intel.c| 3 +--
>  3 files changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/vga/vga_switcheroo.c 
> b/drivers/gpu/vga/vga_switcheroo.c
> index b19a72f..fe32536 100644
> --- a/drivers/gpu/vga/vga_switcheroo.c
> +++ b/drivers/gpu/vga/vga_switcheroo.c
> @@ -290,7 +290,6 @@ EXPORT_SYMBOL(vga_switcheroo_register_client);
>   * @pdev: client pci device
>   * @ops: client callbacks
>   * @id: client identifier, see enum vga_switcheroo_client_id
> - * @active: whether the audio device is fully initialized
>   *
>   * Register audio client (audio device on a GPU). The power state of the
>   * client is assumed to be ON.
> @@ -299,9 +298,9 @@ EXPORT_SYMBOL(vga_switcheroo_register_client);
>   */
>  int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
>const struct vga_switcheroo_client_ops 
> *ops,
> -  int id, bool active)
> +  int id)
>  {
> - return register_client(pdev, ops, id | ID_BIT_AUDIO, active, false);
> + return register_client(pdev, ops, id | ID_BIT_AUDIO, false, false);
>  }
>  EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
>  
> diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
> index fe90bfc..3764991 100644
> --- a/include/linux/vga_switcheroo.h
> +++ b/include/linux/vga_switcheroo.h
> @@ -128,7 +128,7 @@ int vga_switcheroo_register_client(struct pci_dev *dev,
>  bool driver_power_control);
>  int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
>const struct vga_switcheroo_client_ops 
> *ops,
> -  int id, bool active);
> +  int id);
>  
>  void vga_switcheroo_client_fb_set(struct pci_dev *dev,
> struct fb_info *info);
> @@ -154,7 +154,7 @@ static inline void vga_switcheroo_client_fb_set(struct 
> pci_dev *dev, struct fb_i
>  static inline int vga_switcheroo_register_handler(struct 
> vga_switcheroo_handler *handler) { return 0; }
>  static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
>   const struct vga_switcheroo_client_ops *ops,
> - int id, bool active) { return 0; }
> + int id) { return 0; }
>  static inline void vga_switcheroo_unregister_handler(void) {}
>  static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
>  static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { 
> return VGA_SWITCHEROO_ON; }
> diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
> index c38c68f..e819013 100644
> --- a/sound/pci/hda/hda_intel.c
> +++ b/sound/pci/hda/hda_intel.c
> @@ -1143,8 +1143,7 @@ static int register_vga_switcheroo(struct azx *chip)
>* is there any machine with two switchable HDMI audio controllers?
>*/
>   err = vga_switcheroo_register_audio_client(chip->pci, _vs_ops,
> - VGA_SWITCHEROO_DIS,
> - hda->probe_continued);
> +VGA_SWITCHEROO_DIS);
>   if (err < 0)
>   return err;
>   hda->vga_switcheroo_registered = 1;
> -- 
> 1.8.5.2 (Apple Git-48)
> 
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH RFC 0/8] Add New DRM Driver for Hisilicon's Hi6220 SoC

2015-09-17 Thread Xinliang Liu
On 17 September 2015 at 04:16, Daniel Vetter  wrote:

> On Wed, Sep 16, 2015 at 04:23:35PM +0100, Daniel Stone wrote:
> > The biggest issue though, is that this driver should become an atomic
> > modesetting driver. Atomic modesetting, rather than sending small
> > individual commands (enable CRTC, change plane position, etc) is based
> > on validating and passing around complete sets of hardware state.
> > Daniel Vetter's blog has an article on how to convert your driver:
> > http://blog.ffwll.ch/2014/11/atomic-modeset-support-for-kms-drivers.html
>
> Yeah, any new driver should really be built on top of atomic - it's a lot
> more flexible than the old thing and it's also what you want long-term.
>
> I've also just done a presenation about atomic for drivers:
>
> http://people.freedesktop.org/~danvet/presentations/xdc-2015.pdf


Hi Daniel,
This is a good presentation. It gives us very detail and good suggection on
implementation.
Thank you for sharing this.

We have a open source KMS hwc:
wiki:
https://wiki.linaro.org/BenjaminGaignard/HWComposer_DRM?highlight=%28hwcomposer%2
source code: git://git.linaro.org/people/benjamin.gaignard/hwcomposer.git
Now only STI and Hikey boards are tested on it. And atomic mode setting is
not support now.
I think we should add support for atomic mode setting next.

One difficulty I am facing is that one setting should be made sure is ok in
the prepare function of hwc.
If not, the set function of hwc may be fail and display will not properly.
I don't know atomic mode setting how to handle this situation. And it seems
that in the prepare function,
it should check the hardware's capabilities, such as clip, scale, rotation,
blending and so on.

Thanks,
-Xinliang

>
>
> Cheers, Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150917/6ad867d8/attachment.html>


[PATCH] drm/i915: make prelim hw msg in log a bit more harsh

2015-09-17 Thread Rob Clark
Apparently some people see this message and try to turn on
preliminary_hw_support.  And then for some reason are surprised
when it doesn't work.  So let's set expectations a bit lower.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/i915/i915_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8edcec8..5e87fe1 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -926,7 +926,8 @@ static int i915_pci_probe(struct pci_dev *pdev, const 
struct pci_device_id *ent)

if (IS_PRELIMINARY_HW(intel_info) && !i915.preliminary_hw_support) {
DRM_INFO("This hardware requires preliminary hardware 
support.\n"
-"See CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT, and/or 
modparam preliminary_hw_support\n");
+"See CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT, and/or 
modparam preliminary_hw_support.\n"
+"Note that preliminary hw support is unsupported, use 
at your own risk!\n");
return -ENODEV;
}

-- 
2.4.3



[PATCH RFC 0/8] Add New DRM Driver for Hisilicon's Hi6220 SoC

2015-09-17 Thread Xinliang Liu
On 16 September 2015 at 23:23, Daniel Stone  wrote:
Hi Daniel, thank you so much for your good advice:-)
I am xinwei write the hisi drm driver together. I'll reply your comments.

> Hi Xinwei,
> Thanks for this contribution! We look forward to seeing support for
> these devices.
>
> This isn't an exhaustive review, but two very high-level comments
> which should result in a lot of changes ...
>
> On 15 September 2015 at 10:37, Xinwei Kong
>  wrote:
> > 1. Hardware Detail
> >   The display subsystem of Hi6220 SoC is shown as bellow:
> >  +-+   +--+ +-+ +-+
> >  | |   |  | | | | |
> >  | FB  |-->|   ADE|>| DSI |>| External|
> >  | |   |  | | | |  HDMI   |
> >  +-+   +--+ +-+ +-+
> >
> > - ADE(Advanced Display Engine) is the display controller. It contains 7
> > channels or pipes, 3 overlay and a LDI.
> >   - A channel/pipe looks like: DMA-->clip-->scale-->ctrans/csc.
> >   - Overlay is response to compose planes which come from 7 channels and
> >   pass composed image to LDI.
>
> This terminology is backwards from what we usually use in DRM, where
> an overlay is a special case of DRM planes, and pipes are DRM CRTCs.
>

I think I misunderstood the pipe terminology. I thought pipe is same as
plane before,
but now I understand that a pipe will has its own CRTC and generally
different pipe
handle different display content, right?
And in our SoC, a Overlay component do the same thing as a compositor. And
a channel
may handle the primary plane or a overlay plane.

>
> >   - LDI is response to generate timings and RGB data stream.
> > - DSI converts the RGB data stream from ADE to DSI packets.
> > - External HDMI module is connected with DSI bus. Now Hikey use a ADI's
> >   ADV7533 external HDMI chip.
>
> So this is basically just an implementation detail of DSI?

Yes.


> > 2. Software Detail
> >   About the software organization and implementation detail:
> > We have a main drm platform driver (hisi_drm_drv.c), ade platform driver
> > (hisi_ade.c) and a dsi platform driver (hisi_drm_dsi.c). Ade driver
> > implements the plane and crtc driver interfaces and dsi implements the
> > encoder and connector driver interfaces. We take advantage of component
> > framework to initialize each driver.
> >   In order to support multi coming Hisilicon's SoCs, we plan to separate
> > common driver code and SoC specific implemented code as possiple as we
> can.
> > We abstract an ops for each component(crtc, plane, encoder and connector)
> > to reuse the common interface implementation logic (FIXME: Not sure if we
> > can achieve this target and if it is good or not). Thus, we put these
> > common driver code into hisi_drm_drv/crtc/plane/encoder/connector.c
> files.
>
> Please do not do this; in general, the abstraction layers cause more
> problems than they create. We have only just finished removing all the
> abstraction layers from drivers/gpu/drm/exynos/, which started off
> with exactly the same idea, but only created problems. The issue is
> that every time the DRM core interface changes, you have to make the
> exact same changes in your copies of the interface. In general, there
> seems to be no benefit to having these here: you can just assign the
> DRM functions directly according to generation. See current Exynos for
> an example of this.
>

OK, actually, I also think a  abstraction layer may not good when we finish
it.
We will drop the abstraction in next version of patch.


> The biggest issue though, is that this driver should become an atomic
> modesetting driver. Atomic modesetting, rather than sending small
> individual commands (enable CRTC, change plane position, etc) is based
> on validating and passing around complete sets of hardware state.
>

Is it done by call the DRM_IOCTL_MODE_ATOMIC ioctl in the userland?

Daniel Vetter's blog has an article on how to convert your driver:
> http://blog.ffwll.ch/2014/11/atomic-modeset-support-for-kms-drivers.html
>
> In addition, there are some drivers converted already that you can
> look at: tegra (very simple), exynos (reasonably simple), fsl-dcu
> (moderate), msm (quite complex), i915 (incredibly complex), rcar-du
> (???).
>
> Once your driver is converted to atomic and the abstraction layers
> removed, then it will be much easier to review the submission in
> detail.
>

We have converted to atomic for this version of patches. But maybe we need
to test
atomic mode setting with the DRM_IOCTL_MODE_ATOMIC ioctl.

Thanks,
-Xinliang


> Thanks very much!
>
> Cheers,
> Daniel
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150917/375d1cb8/attachment.html>


vga_switcheroo docs (was: Re: [PATCH v2.1 1/3] vga_switcheroo: Add support for switching only the DDC)

2015-09-17 Thread Lukas Wunner
Hi Daniel,

On Tue, Aug 25, 2015 at 10:12:50AM +0200, Daniel Vetter wrote:
> Since you're just diggin around in switcheroo code it would be awesome to
> write proper kerneldoc for all the functions exposed to drivers, move the
> above to a proper kerneldoc for the vfunc tables

Alright, a patch set with vga_switcheroo docs is coming up right after this
e-mail. I also fixed some bugs and cosmetic issues while I was at it.

To ease reviewing I've pushed this to GitHub:
https://github.com/l1k/linux/commits/vga_switcheroo_docs

Patch #2 requires Markdown support so you may want to postpone that single
patch for now. The patches are based on today's topic/drm-misc.


> (there's new support for adding kerneldoc split up per member instead of
> one big pile squashed at the top).

To be honest the data structures aren't that large so I felt that the
traditional "docs above, struct below" way is clearer and more concise
in this case.


> And then bind it together with the overview sections with DOC
> comments in Documentation/DocBook/drm.tmpl.

vga_switcheroo is a subsystem of its own which interfaces not just with
DRM but also with multiplexer drivers, ALSA and power management,
so I put it in a separate .tmpl file.


Thanks,

Lukas


[PATCH libdrm] intel: Use CPU mmap for unsynchronized map with linear buffers

2015-09-17 Thread ville.syrj...@linux.intel.com
From: Ville Syrjälä 

On LLC platforms there's no need to use GTT mmap for unsynchronized
maps if the object isn't tiled. So switch to using CPU mmap for linar
objects. This avoids having to use the GTT for GL buffer objects
entirely, and thus we can ignore the GTT mappable size limitation.
For tiled objects we still want the hardware to do the (de)tiling so
keep using GTT for such objects.

The display engine is not coherent even on LLC platforms, so this won't
work too well if we mix scanout and unsynchronized maps of linear bos.
Actually, that would only be a problem for an already uncached object,
otherwise it will get clflushed anyway when being made UC/WC prior to
scanout. The alreday UC object case could be handled by either
clflushing straight from userspace, or we could add a new ioctl to
clflush or mark the object as cache_dirty so that it will get
clflushed in the future just prior to scanout. I started to think
that a small nop pwrite would have the desired effect, but in fact it
would only flush the cachelines it touches so wouldn't actually work
I doubt we want to pwrite the entire object just to get it clflushed.

This fixes Ilias's arb_texture_buffer_object-max-size piglit test
on LLC platforms.

Cc: Ilia Mirkin 
Signed-off-by: Ville Syrjälä 
---
 intel/intel_bufmgr_gem.c | 30 +++---
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index 63122d0..5e8335a 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -1337,11 +1337,10 @@ static void drm_intel_gem_bo_unreference(drm_intel_bo 
*bo)
}
 }

-static int drm_intel_gem_bo_map(drm_intel_bo *bo, int write_enable)
+static int map_cpu(drm_intel_bo *bo)
 {
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
-   struct drm_i915_gem_set_domain set_domain;
int ret;

if (bo_gem->is_userptr) {
@@ -1350,8 +1349,6 @@ static int drm_intel_gem_bo_map(drm_intel_bo *bo, int 
write_enable)
return 0;
}

-   pthread_mutex_lock(_gem->lock);
-
if (bo_gem->map_count++ == 0)
drm_intel_gem_bo_open_vma(bufmgr_gem, bo_gem);

@@ -1384,6 +1381,24 @@ static int drm_intel_gem_bo_map(drm_intel_bo *bo, int 
write_enable)
bo_gem->mem_virtual);
bo->virtual = bo_gem->mem_virtual;

+   return 0;
+}
+
+static int drm_intel_gem_bo_map(drm_intel_bo *bo, int write_enable)
+{
+   drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
+   drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+   struct drm_i915_gem_set_domain set_domain;
+   int ret;
+
+   pthread_mutex_lock(_gem->lock);
+
+   ret = map_cpu(bo);
+   if (ret || bo_gem->is_userptr) {
+   pthread_mutex_unlock(_gem->lock);
+   return ret;
+   }
+
memclear(set_domain);
set_domain.handle = bo_gem->gem_handle;
set_domain.read_domains = I915_GEM_DOMAIN_CPU;
@@ -1536,9 +1551,7 @@ int
 drm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo)
 {
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
-#ifdef HAVE_VALGRIND
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
-#endif
int ret;

/* If the CPU cache isn't coherent with the GTT, then use a
@@ -1553,7 +1566,10 @@ drm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo)

pthread_mutex_lock(_gem->lock);

-   ret = map_gtt(bo);
+   if (bo_gem->tiling_mode == I915_TILING_NONE)
+   ret = map_cpu(bo);
+   else
+   ret = map_gtt(bo);
if (ret == 0) {
drm_intel_gem_bo_mark_mmaps_incoherent(bo);
VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->gtt_virtual, bo->size));
-- 
2.4.6



[PATCH RFC 5/8] drm: hisilicon: fill interface function of encoder\connector part

2015-09-17 Thread Archit Taneja


On 9/15/2015 3:07 PM, Xinwei Kong wrote:
> This patch enables the adv7533 module which is connecting hisilicon SOC
> by dsi module. while using DSI module and adv7533 module to implement the
> encoder/connector interface of DRM\KMS.
>
> Signed-off-by: Xinliang Liu 
> Signed-off-by: Xinwei Kong 
> Signed-off-by: Andy Green 
> Signed-off-by: Jiwen Qi 
> Signed-off-by: Yu Gong 
> ---
>   drivers/gpu/drm/hisilicon/Kconfig  |  10 +
>   drivers/gpu/drm/hisilicon/hisi_drm_connector.c |  34 ++
>   drivers/gpu/drm/hisilicon/hisi_drm_connector.h |   8 +
>   drivers/gpu/drm/hisilicon/hisi_drm_dsi.c   | 670 
> +
>   drivers/gpu/drm/hisilicon/hisi_drm_encoder.c   |  52 ++
>   drivers/gpu/drm/hisilicon/hisi_drm_encoder.h   |  19 +
>   drivers/gpu/drm/hisilicon/hisi_dsi_reg.h   |  91 
>   7 files changed, 884 insertions(+)
>   create mode 100644 drivers/gpu/drm/hisilicon/hisi_dsi_reg.h
>



> +struct hisi_connector_funcs hisi_dsi_connector_ops = {
> + .get_modes = dsi_connector_get_modes,
> +};
> +
> +struct hisi_encoder_funcs hisi_dsi_encoder_ops = {
> + .mode_set = dsi_encoder_mode_set,
> + .enable = dsi_encoder_enable,
> + .disable = dsi_encoder_disable,
> +};
> +
>   static int hisi_dsi_bind(struct device *dev, struct device *master,
>void *data)
>   {
> @@ -52,8 +682,23 @@ static int hisi_dsi_bind(struct device *dev, struct 
> device *master,
>
>   hisi_drm_encoder_init(ctx->dev, >dsi.hisi_encoder.base.base);
>
> +#ifdef CONFIG_DRM_HISI_HAS_SLAVE_ENCODER
> + ret = ctx->drm_i2c_driver->encoder_init(ctx->client, ctx->dev,
> + >dsi.hisi_encoder.base);
> + if (ret) {
> + DRM_ERROR("fail to init drm i2c encoder\n");
> + return ret;
> + }
> +
> + if (!ctx->dsi.hisi_encoder.base.slave_funcs) {
> + DRM_ERROR("failed check encoder function\n");
> + return -ENODEV;
> + }
> +#endif

A slave encoder isn't supposed to be used this way. A slave encoder is
supposed to register itself to drm as an encoder object. A slave
encoder connects directly to a crtc, and operate like a normal encoder.
In other words, a slave encoder isn't something that attaches to a
'master' encoder as the driver does here. 'Slave encoder' here means
that the encoder is a part of a different bus (like i2c etc).

Currently, the driver is directly calling slave encoder ops in 
hisi_drm_encoder.c.


> +
>   hisi_drm_connector_init(ctx->dev, >dsi.hisi_encoder.base.base,
>   >dsi.hisi_connector.connector);
> +
>   return ret;
>   }
>
> @@ -102,6 +747,27 @@ static int hisi_dsi_probe(struct platform_device *pdev)
>   return -EINVAL;
>   }
>
> +#ifdef CONFIG_DRM_HISI_HAS_SLAVE_ENCODER
> + ctx->client = of_find_i2c_device_by_node(slave_node);
> + of_node_put(slave_node);
> + if (!ctx->client) {
> + DRM_ERROR("failed to find slave encoder i2c client\n");
> + return -EPROBE_DEFER;
> + }
> +
> + if (!ctx->client->dev.driver) {
> + DRM_ERROR("%s: NULL client driver\n", __func__);
> + return -EPROBE_DEFER;
> + }
> +
> + ctx->drm_i2c_driver = to_drm_i2c_encoder_driver(
> + to_i2c_driver(ctx->client->dev.driver));
> + if (IS_ERR(ctx->drm_i2c_driver)) {
> + DRM_ERROR("failed to initialize encoder driver");
> + return -EPROBE_DEFER;
> + }
> +#endif
> +
>   dsi = >dsi;
>   dsi->ctx = ctx;
>   dsi->lanes = 3;
> @@ -110,6 +776,10 @@ static int hisi_dsi_probe(struct platform_device *pdev)
>   dsi->format = MIPI_DSI_FMT_RGB888;
>   dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
>
> + dsi->hisi_encoder.ops = _dsi_encoder_ops;
> + dsi->hisi_connector.encoder = >hisi_encoder.base.base;
> + dsi->hisi_connector.ops = _dsi_connector_ops;
> +
>   return component_add(>dev, _dsi_ops);
>   }
>
> diff --git a/drivers/gpu/drm/hisilicon/hisi_drm_encoder.c 
> b/drivers/gpu/drm/hisilicon/hisi_drm_encoder.c
> index 89fc73d..acd73d8 100644
> --- a/drivers/gpu/drm/hisilicon/hisi_drm_encoder.c
> +++ b/drivers/gpu/drm/hisilicon/hisi_drm_encoder.c
> @@ -15,18 +15,49 @@
>
>   #include "hisi_drm_encoder.h"
>
> +#define to_hisi_encoder(encoder) \
> + container_of(encoder, struct hisi_encoder, base.base)
> +
>   void hisi_drm_encoder_disable(struct drm_encoder *encoder)
>   {
> + struct hisi_encoder *hencoder = to_hisi_encoder(encoder);
> + struct hisi_encoder_funcs *ops = hencoder->ops;
> + struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder);
> +
> + if (ops->enable)
> + ops->disable(encoder);
> +
> + if (sfuncs && sfuncs->dpms)
> + sfuncs->dpms(encoder, DRM_MODE_DPMS_OFF);
>   }
>

The encoder should represent only the DSI encoder hardware here. It
shouldn't be calling slave encoder ops.

What you want is to 

[PATCH 1/5] drm: atmel-hlcdc: Fix module autoload for OF platform driver

2015-09-17 Thread Boris Brezillon
Hi Luis,

On Thu, 17 Sep 2015 16:20:43 +0200
Luis de Bethencourt  wrote:

> This platform driver has a OF device ID table but the OF module
> alias information is not created so module autoloading won't work.
> 
> Signed-off-by: Luis de Bethencourt 

Acked-by: Boris Brezillon 

Thanks,

Boris

> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c 
> b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index 8bc62ec..a83c431 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -342,6 +342,7 @@ static const struct of_device_id atmel_hlcdc_of_match[] = 
> {
>   },
>   { /* sentinel */ },
>  };
> +MODULE_DEVICE_TABLE(of, atmel_hlcdc_of_match);
>  
>  int atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc,
> struct drm_display_mode *mode)



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


[PATCH] drm/mgag200: Fix calling drm_fb_helper_fini() twice

2015-09-17 Thread Sudip Mukherjee
On Thu, Sep 17, 2015 at 04:24:21PM +0530, Archit Taneja wrote:
> 
> 
> On 9/17/2015 2:04 PM, Ingo Molnar wrote:
> >
> >
> >* Ingo Molnar  wrote:
> >
> >
> >
> >>So this patch was whitespace damaged - I applied it by hand and made the 
> >>commit
> >
> >>below. This has solved the crash, thanks Archit!
> >
> >
> >
> >Spoke too soon - the attached (allyesconfig-ish) config still crashes, first 
> >there
> >
> >are a handful of kobject debug warnings, then:
> 
> The error handling in the driver is bad. The main problem is that
> the driver_load op calls mgag200_driver_unload if anything fails,
> which doesn't work well if driver_load fails mid way.
mgag200_driver_unload is trying to unload everything evenif that has not
succeeded in initializing. Here the ttm failed to initialize but
still mgag200_mm_fini was called to unload it.

regards
sudip


[PATCH RFC 2/8] drm: hisilicon: Add new DRM driver for hisilicon Soc

2015-09-17 Thread Archit Taneja
Hi,

On 9/15/2015 3:07 PM, Xinwei Kong wrote:
> This patch creates this driver itself and register all the sub-components
> which is from DTS inode, this driver uses components framework mechanism
> to bind all the sub-components.
>
> This patch also introduces a memory manager for hisilison drm. As cma
> framebuffer helpers can no more be used.
>
> Signed-off-by: Xinliang Liu 
> Signed-off-by: Xinwei Kong 
> Signed-off-by: Andy Green 
> Signed-off-by: Jiwen Qi 
> Signed-off-by: Yu Gong 
> ---
>   arch/arm64/configs/defconfig |   5 +
>   drivers/gpu/drm/Kconfig  |   2 +
>   drivers/gpu/drm/Makefile |   1 +
>   drivers/gpu/drm/hisilicon/Kconfig|   9 ++
>   drivers/gpu/drm/hisilicon/Makefile   |   7 ++
>   drivers/gpu/drm/hisilicon/hisi_ade.c | 166 +
>   drivers/gpu/drm/hisilicon/hisi_drm_drv.c | 206 
> +++
>   drivers/gpu/drm/hisilicon/hisi_drm_dsi.c | 131 
>   drivers/gpu/drm/hisilicon/hisi_drm_fb.c  | 156 +++
>   drivers/gpu/drm/hisilicon/hisi_drm_fb.h  |  26 
>   10 files changed, 709 insertions(+)
>   create mode 100644 drivers/gpu/drm/hisilicon/Kconfig
>   create mode 100644 drivers/gpu/drm/hisilicon/Makefile
>   create mode 100644 drivers/gpu/drm/hisilicon/hisi_ade.c
>   create mode 100644 drivers/gpu/drm/hisilicon/hisi_drm_drv.c
>   create mode 100644 drivers/gpu/drm/hisilicon/hisi_drm_dsi.c
>   create mode 100644 drivers/gpu/drm/hisilicon/hisi_drm_fb.c
>   create mode 100644 drivers/gpu/drm/hisilicon/hisi_drm_fb.h
>



> diff --git a/drivers/gpu/drm/hisilicon/hisi_drm_dsi.c 
> b/drivers/gpu/drm/hisilicon/hisi_drm_dsi.c
> new file mode 100644
> index 000..a8dbaad
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hisi_drm_dsi.c
> @@ -0,0 +1,131 @@
> +/*
> + * Hisilicon Terminal SoCs drm driver
> + *
> + * Copyright (c) 2014-2015 Hisilicon Limited.
> + * Author: Xinwei Kong  for hisilicon
> + *
> + * 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 
> +
> +#define DSI_24BITS_1   (5)
> +
> +struct hisi_dsi {
> + u32 lanes;
> + u32 format;
> + u32 date_enable_pol;
> + u32 mode_flags;
> + u8 color_mode;
> + void *ctx;
> +};
> +
> +struct hisi_dsi_context {
> + struct hisi_dsi dsi;
> + struct clk *dsi_cfg_clk;
> + struct drm_device *dev;
> +
> + void __iomem *base;
> + int nominal_pixel_clk_kHz;
> +};
> +
> +static int hisi_dsi_bind(struct device *dev, struct device *master,
> +  void *data)
> +{
> + int ret = 0;
> +
> + return ret;
> +}
> +
> +static void hisi_dsi_unbind(struct device *dev, struct device *master,
> + void *data)
> +{
> + /* do nothing */
> +}
> +
> +static const struct component_ops hisi_dsi_ops = {
> + .bind   = hisi_dsi_bind,
> + .unbind = hisi_dsi_unbind,
> +};
> +
> +static int hisi_dsi_probe(struct platform_device *pdev)
> +{
> + struct hisi_dsi_context *ctx;
> + struct hisi_dsi *dsi;
> + struct resource *res;
> + struct device_node *slave_node;
> + struct device_node *np = pdev->dev.of_node;
> + int ret;
> +
> + ctx = devm_kzalloc(>dev, sizeof(*ctx), GFP_KERNEL);
> + if (!ctx) {
> + DRM_ERROR("failed to allocate hisi dsi context.\n");
> + ret = -ENOMEM;
> + }
> +
> + ctx->dsi_cfg_clk = devm_clk_get(>dev, "pclk_dsi");
> + if (IS_ERR(ctx->dsi_cfg_clk)) {
> + DRM_ERROR("failed to parse the dsi config clock\n");
> + ret = PTR_ERR(ctx->dsi_cfg_clk);
> + }
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + ctx->base = devm_ioremap_resource(>dev, res);
> + if (IS_ERR(ctx->base)) {
> + DRM_ERROR("failed to remap dsi io region\n");
> + ret = PTR_ERR(ctx->base);
> + }
> +
> + slave_node = of_parse_phandle(np, "encoder-slave", 0);
> + if (!slave_node) {
> + DRM_ERROR("failed to parse the slave encoder node\n");
> + return -EINVAL;
> + }
> +
> + dsi = >dsi;
> + dsi->ctx = ctx;
> + dsi->lanes = 3;
> + dsi->date_enable_pol = 0;
> + dsi->color_mode = DSI_24BITS_1;
> + dsi->format = MIPI_DSI_FMT_RGB888;
> + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
> +
> + return component_add(>dev, _dsi_ops);
> +}
> +

The DSI driver should register the dsi host via 
mipi_dsi_host_register(). That's the standard way of establishing a
connection between a host and dsi peripherals.

The dsi_context approach isn't something that will work very well.
With this approach, you're forced to set DSI parameters like number of
lanes, format, mode flags etc in the host driver, rather than 

[PATCH 2/2] drm/mgag200: Fix driver_load error handling

2015-09-17 Thread Archit Taneja
mgag200_driver_load's error path just calls the drm driver's
driver_unload op. It isn't safe to call this because it doesn't handle
things well if driver_load fails somewhere mid way.

Replace the call to mgag200_driver_unload with a more finegrained
error handling path.

Link: http://lkml.kernel.org/r/55F6E68D.8070800 at codeaurora.org
Reported-by: Ingo Molnar 
Cc: Daniel Vetter 
Cc: Dave Airlie 
Cc: David Airlie 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Sudip Mukherjee 
Cc: Thomas Gleixner 
Cc: dri-devel 
Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/mgag200/mgag200_main.c | 36 +++---
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c 
b/drivers/gpu/drm/mgag200/mgag200_main.c
index de06388..b1a0f56 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -220,7 +220,7 @@ int mgag200_driver_load(struct drm_device *dev, unsigned 
long flags)
}
r = mgag200_mm_init(mdev);
if (r)
-   goto out;
+   goto err_mm;

drm_mode_config_init(dev);
dev->mode_config.funcs = (void *)_mode_funcs;
@@ -233,7 +233,7 @@ int mgag200_driver_load(struct drm_device *dev, unsigned 
long flags)
r = mgag200_modeset_init(mdev);
if (r) {
dev_err(>pdev->dev, "Fatal error during modeset init: 
%d\n", r);
-   goto out;
+   goto err_modeset;
}

/* Make small buffers to store a hardware cursor (double buffered icon 
updates) */
@@ -241,20 +241,24 @@ int mgag200_driver_load(struct drm_device *dev, unsigned 
long flags)
  >cursor.pixels_1);
mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
  >cursor.pixels_2);
-   if (!mdev->cursor.pixels_2 || !mdev->cursor.pixels_1)
-   goto cursor_nospace;
-   mdev->cursor.pixels_current = mdev->cursor.pixels_1;
-   mdev->cursor.pixels_prev = mdev->cursor.pixels_2;
-   goto cursor_done;
- cursor_nospace:
-   mdev->cursor.pixels_1 = NULL;
-   mdev->cursor.pixels_2 = NULL;
-   dev_warn(>pdev->dev, "Could not allocate space for cursors. Not 
doing hardware cursors.\n");
- cursor_done:
-
-out:
-   if (r)
-   mgag200_driver_unload(dev);
+   if (!mdev->cursor.pixels_2 || !mdev->cursor.pixels_1) {
+   mdev->cursor.pixels_1 = NULL;
+   mdev->cursor.pixels_2 = NULL;
+   dev_warn(>pdev->dev,
+   "Could not allocate space for cursors. Not doing 
hardware cursors.\n");
+   } else {
+   mdev->cursor.pixels_current = mdev->cursor.pixels_1;
+   mdev->cursor.pixels_prev = mdev->cursor.pixels_2;
+   }
+
+   return 0;
+
+err_modeset:
+   drm_mode_config_cleanup(dev);
+   mgag200_mm_fini(mdev);
+err_mm:
+   dev->dev_private = NULL;
+
return r;
 }

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



[PATCH 1/2] drm/mgag200: Fix error handling paths in fbdev driver

2015-09-17 Thread Archit Taneja
Set up error handling in mgag200_fbdev_init and mgag200fb_create such that
they release the things they allocate, rather than relying on someone
calling mga_fbdev_destroy.

Based on a patch by Sudip Mukherjee 

Link: http://lkml.kernel.org/r/55F6E68D.8070800 at codeaurora.org
Reported-by: Ingo Molnar 
Cc: Daniel Vetter 
Cc: Dave Airlie 
Cc: David Airlie 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Sudip Mukherjee 
Cc: Thomas Gleixner 
Cc: dri-devel 
Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/mgag200/mgag200_fb.c | 31 +++
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c 
b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 87de15e..b35b5b2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -186,17 +186,19 @@ static int mgag200fb_create(struct drm_fb_helper *helper,

sysram = vmalloc(size);
if (!sysram)
-   return -ENOMEM;
+   goto err_sysram;

info = drm_fb_helper_alloc_fbi(helper);
-   if (IS_ERR(info))
-   return PTR_ERR(info);
+   if (IS_ERR(info)) {
+   ret = PTR_ERR(info);
+   goto err_alloc_fbi;
+   }

info->par = mfbdev;

ret = mgag200_framebuffer_init(dev, >mfb, _cmd, gobj);
if (ret)
-   return ret;
+   goto err_framebuffer_init;

mfbdev->sysram = sysram;
mfbdev->size = size;
@@ -225,7 +227,17 @@ static int mgag200fb_create(struct drm_fb_helper *helper,

DRM_DEBUG_KMS("allocated %dx%d\n",
  fb->width, fb->height);
+
return 0;
+
+err_framebuffer_init:
+   drm_fb_helper_release_fbi(helper);
+err_alloc_fbi:
+   vfree(sysram);
+err_sysram:
+   drm_gem_object_unreference_unlocked(gobj);
+
+   return ret;
 }

 static int mga_fbdev_destroy(struct drm_device *dev,
@@ -276,23 +288,26 @@ int mgag200_fbdev_init(struct mga_device *mdev)
ret = drm_fb_helper_init(mdev->dev, >helper,
 mdev->num_crtc, MGAG200FB_CONN_LIMIT);
if (ret)
-   return ret;
+   goto err_fb_helper;

ret = drm_fb_helper_single_add_all_connectors(>helper);
if (ret)
-   goto fini;
+   goto err_fb_setup;

/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(mdev->dev);

ret = drm_fb_helper_initial_config(>helper, bpp_sel);
if (ret)
-   goto fini;
+   goto err_fb_setup;

return 0;

-fini:
+err_fb_setup:
drm_fb_helper_fini(>helper);
+err_fb_helper:
+   mdev->mfbdev = NULL;
+
return ret;
 }

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



[PATCH] drm/mgag200: Fix calling drm_fb_helper_fini() twice

2015-09-17 Thread Archit Taneja


On 9/17/2015 2:04 PM, Ingo Molnar wrote:
>
>
> * Ingo Molnar  wrote:
>
>
>
>> So this patch was whitespace damaged - I applied it by hand and made the 
>> commit
>
>> below. This has solved the crash, thanks Archit!
>
>
>
> Spoke too soon - the attached (allyesconfig-ish) config still crashes, first 
> there
>
> are a handful of kobject debug warnings, then:

The error handling in the driver is bad. The main problem is that the 
driver_load op calls mgag200_driver_unload if anything fails, which 
doesn't work well if driver_load fails mid way.

I'll post out patches to fix this. But you'll need to undo the patch
I'd sent previously.

Thanks,
Archit

>
>
>
> [  115.274847] [drm:mgag200_mm_init] *ERROR* Failed setting up TTM memory 
> accounting subsystem.
>
> [  115.274853] BUG: unable to handle kernel NULL pointer dereference at   
> (null)
>
> [  115.274856] IP: [] drm_mode_config_cleanup+0x1f/0x1cc
>
> [  115.274858] PGD 0
>
> [  115.274860] Oops:  [#1] SMP DEBUG_PAGEALLOC KASAN
>
> [  115.274861] Modules linked in:
>
> [  115.274862] CPU: 0 PID: 4 Comm: kworker/0:0 Tainted: GWL  
> 4.3.0-rc1-01729-g525850e-dirty #59
>
> [  115.274863] Hardware name: Intel Corporation S2600GZ/S2600GZ, BIOS 
> SE5C600.86B.02.02.0002.122320131210 12/23/2013
>
> [  115.274865] Workqueue: events work_for_cpu_fn
>
> [  115.274865] task: 88017d2a8000 ti: 88017d2b task.ti: 
> 88017d2b
>
> [  115.274868] RIP: 0010:[]  [] 
> drm_mode_config_cleanup+0x1f/0x1cc
>
> [  115.274868] RSP: :88017d2b7bd8  EFLAGS: 00010246
>
> [  115.274869] RAX:  RBX: 8800ba0a4520 RCX: 
> 81186ff1
>
> [  115.274870] RDX: 88017d2b7a90 RSI: 83d73579 RDI: 
> 8800ba0a4520
>
> [  115.274870] RBP: 88017d2b7bf0 R08: 0001 R09: 
> 
>
> [  115.274871] R10: 00075000 R11: 85147a82 R12: 
> 8800ba0a4520
>
> [  115.274872] R13: 8800ba0a4da8 R14: fffe R15: 
> 8800ba0a3400
>
> [  115.274873] FS:  () GS:880420e0() 
> knlGS:
>
> [  115.274874] CS:  0010 DS:  ES:  CR0: 80050033
>
> [  115.274875] CR2:  CR3: 05e2d000 CR4: 
> 001406f0
>
> [  115.274876] Stack:
>
> [  115.274877]  8800ba0a3400 8800ba0a4520 fffe 
> 88017d2b7c10
>
> [  115.274879]  81cb6a3e 8800ba0a4520 8800ba0a3400 
> 88017d2b7c78
>
> [  115.274881]  81cb6efe 07200100 aa55 
> 075b
>
> [  115.274881] Call Trace:
>
> [  115.274883]  [] mgag200_driver_unload+0x30/0x48
>
> [  115.274884]  [] mgag200_driver_load+0x4a8/0x4ba
>
> [  115.274886]  [] drm_dev_register+0x6f/0xb0
>
> [  115.274887]  [] drm_get_pci_dev+0xff/0x1c2
>
> [  115.274889]  [] mga_pci_probe+0xa6/0xad
>
> [  115.274890]  [] local_pci_probe+0x3d/0x82
>
> [  115.274891]  [] work_for_cpu_fn+0x14/0x1b
>
> [  115.274893]  [] process_one_work+0x28e/0x4ef
>
> [  115.274895]  [] ? process_one_work+0x170/0x4ef
>
> [  115.274897]  [] process_scheduled_works+0x21/0x2f
>
>
>
> Full log is below, config attached as well.
>
>
>
> Thanks,
>
>
>
>   Ingo
>
>
>
> >
>
> [  115.243547] mgag200 :0b:00.0: no default pinctrl state
>
> [  115.243732] devices_kset: Moving :0b:00.0 to end of list
>
> [  115.247078] device: 'controlD64': device_add
>
> [  115.247494] PM: Adding info for No Bus:controlD64
>
> [  115.247979] device: 'card0': device_add
>
> [  115.248315] PM: Adding info for No Bus:card0
>
> [  115.274511] [ cut here ]
>
> [  115.274518] WARNING: CPU: 0 PID: 4 at lib/kobject.c:582 
> kobject_get+0x33/0x6a()
>
> [  115.274519] kobject: 'ttm' (86c28700): is not initialized, yet 
> kobject_get() is being called.
>
> [  115.274521] Modules linked in:
>
> [  115.274524] CPU: 0 PID: 4 Comm: kworker/0:0 Tainted: GWL  
> 4.3.0-rc1-01729-g525850e-dirty #59
>
> [  115.274525] Hardware name: Intel Corporation S2600GZ/S2600GZ, BIOS 
> SE5C600.86B.02.02.0002.122320131210 12/23/2013
>
> [  115.274529] Workqueue: events work_for_cpu_fn
>
> [  115.274532]   88017d2b79a8 8188f38b 
> 88017d2b79f0
>
> [  115.274534]  88017d2b79e0 81144593 8189129f 
> 86c28700
>
> [  115.274536]   86c28700 007f4000 
> 88017d2b7a40
>
> [  115.274537] Call Trace:
>
> [  115.274540]  [] dump_stack+0x4b/0x64
>
> [  115.274543]  [] warn_slowpath_common+0x9f/0xb8
>
> [  115.274545]  [] ? kobject_get+0x33/0x6a
>
> [  115.274547]  [] warn_slowpath_fmt+0x4c/0x4e
>
> [  115.274551]  [] ? lock_is_held+0x55/0x66
>
> [  115.274553]  [] kobject_get+0x33/0x6a
>
> [  115.274554]  [] kobject_add_internal+0x58/0x2c4
>
> [  115.274556]  [] kobject_init_and_add+0x73/0x7e
>
> [  115.274559]  [] ttm_mem_global_init+0xc6/0x2cd
>
> [  115.274563]  [] ? kasan_poison_shadow+0x2f/0x31
>
> [  115.274564]  [] 

[PATCH 4/5] drm/rockchip: Fix module autoload for OF platform driver

2015-09-17 Thread Luis de Bethencourt
This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 5d8ae5e..5897851 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -374,6 +374,7 @@ static const struct of_device_id vop_driver_dt_match[] = {
  .data = _vop },
{},
 };
+MODULE_DEVICE_TABLE(of, vop_driver_dt_match);

 static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)
 {
-- 
2.4.6



[PATCH 3/5] drm: omapdrm: tiler: Fix module autoload for OF platform driver

2015-09-17 Thread Luis de Bethencourt
This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt 
---
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c 
b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 7841970..ecbc9e5 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -1014,6 +1014,7 @@ static const struct of_device_id dmm_of_match[] = {
},
{},
 };
+MODULE_DEVICE_TABLE(of, dmm_of_match);
 #endif

 struct platform_driver omap_dmm_driver = {
-- 
2.4.6



[PATCH 2/5] drm: imx: imx-tve: Fix module autoload for OF platform driver

2015-09-17 Thread Luis de Bethencourt
This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt 
---
 drivers/gpu/drm/imx/imx-tve.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index e671ad3..f959714 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -721,6 +721,7 @@ static const struct of_device_id imx_tve_dt_ids[] = {
{ .compatible = "fsl,imx53-tve", },
{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, imx_tve_dt_ids);

 static struct platform_driver imx_tve_driver = {
.probe  = imx_tve_probe,
-- 
2.4.6



[PATCH 1/5] drm: atmel-hlcdc: Fix module autoload for OF platform driver

2015-09-17 Thread Luis de Bethencourt
This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt 
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 8bc62ec..a83c431 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -342,6 +342,7 @@ static const struct of_device_id atmel_hlcdc_of_match[] = {
},
{ /* sentinel */ },
 };
+MODULE_DEVICE_TABLE(of, atmel_hlcdc_of_match);

 int atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc,
  struct drm_display_mode *mode)
-- 
2.4.6



[PATCH 0/5] drm: Fix module autoload for OF platform drivers

2015-09-17 Thread Luis de Bethencourt
These patches add the missing MODULE_DEVICE_TABLE() for OF to export
the information so modules have the correct aliases built-in and
autoloading works correctly.

A longer explanation by Javier Canillas can be found here:
https://lkml.org/lkml/2015/7/30/519

Thanks,
Luis

Luis de Bethencourt (5):
  drm: atmel-hlcdc: Fix module autoload for OF platform driver
  drm: imx: imx-tve: Fix module autoload for OF platform driver
  drm: omapdrm: tiler: Fix module autoload for OF platform driver
  drm/rockchip: Fix module autoload for OF platform driver
  drm/tegra: Fix module autoload for OF platform driver

 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 1 +
 drivers/gpu/drm/imx/imx-tve.c| 1 +
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 1 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c  | 1 +
 drivers/gpu/drm/tegra/drm.c  | 1 +
 5 files changed, 5 insertions(+)

-- 
2.4.6



[PATCH 01/15] vga_switcheroo: Document _ALL_ the things!

2015-09-17 Thread Lukas Wunner
This adds an "Overview" DOC section plus two DOC sections for the modes
of use ("Manual switching and manual power control" and "Driver power
control").

Also included is kernel-doc for all public functions, structs and enums.

Signed-off-by: Lukas Wunner 
---
 drivers/gpu/vga/vga_switcheroo.c | 285 +--
 include/linux/vga_switcheroo.h   |  85 +++-
 2 files changed, 353 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 2106066..b19a72f 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -1,20 +1,31 @@
 /*
+ * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
+ *
  * Copyright (c) 2010 Red Hat Inc.
  * Author : Dave Airlie 
  *
+ * Copyright (c) 2015 Lukas Wunner 
  *
- * Licensed under GPLv2
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
  *
- * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
  *
- * Switcher interface - methods require for ATPX and DCM
- * - switchto - this throws the output MUX switch
- * - discrete_set_power - sets the power state for the discrete card
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS
+ * IN THE SOFTWARE.
  *
- * GPU driver interface
- * - set_gpu_state - this should do the equiv of s/r for the card
- * - this should *not* set the discrete power state
- * - switch_check  - check if the device is in a position to switch now
  */

 #define pr_fmt(fmt) "vga_switcheroo: " fmt
@@ -33,6 +44,61 @@

 #include 

+/**
+ * DOC: Overview
+ *
+ * vga_switcheroo is the Linux subsystem for laptop hybrid graphics.
+ * These come in two flavors:
+ *
+ * * muxed: Dual GPUs with a multiplexer chip to switch outputs between GPUs.
+ * * muxless: Dual GPUs but only one of them is connected to outputs.
+ * The other one is merely used to offload rendering, its results
+ * are copied over PCIe into the framebuffer. On Linux this is
+ * supported with DRI PRIME.
+ *
+ * Hybrid graphics started to appear in the late Naughties and were initially
+ * all muxed. Newer laptops moved to a muxless architecture for cost reasons.
+ * A notable exception is the MacBook Pro which continues to use a mux.
+ * Muxes come with varying capabilities: Some switch only the panel, others
+ * can also switch external displays. Some switch all display pins at once
+ * while others can switch just the DDC lines. (To allow EDID probing
+ * for the inactive GPU.) Also, muxes are often used to cut power to the
+ * discrete GPU while it is not used.
+ *
+ * DRM drivers register GPUs with vga_switcheroo, these are heretoforth called
+ * clients. The mux is called the handler. Muxless machines also register a
+ * handler to control the power state of the discrete GPU, its ->switchto
+ * callback is a no-op for obvious reasons. The discrete GPU is often equipped
+ * with an HDA controller for the HDMI/DP audio signal, this will also
+ * register as a client so that vga_switcheroo can take care of the correct
+ * suspend/resume order when changing the discrete GPU's power state. In total
+ * there can thus be up to three clients: Two vga clients (GPUs) and one audio
+ * client (on the discrete GPU). The code is mostly prepared to support
+ * machines with more than two GPUs should they become available.
+ * The GPU to which the outputs are currently switched is called the
+ * active client in vga_switcheroo parlance. The GPU not in use is the
+ * inactive client.
+ */
+
+/**
+ * struct vga_switcheroo_client - registered client
+ * @pdev: client pci device
+ * @fb_info: framebuffer to which console is remapped on switching
+ * @pwr_state: current power state
+ * @ops: client callbacks
+ * @id: client identifier, see enum vga_switcheroo_client_id.
+ * Determining the id requires the handler, so GPUs are initially
+ * assigned -1 and later given their true id in vga_switcheroo_enable()
+ * @active: whether 

[PATCH 03/15] vga_switcheroo: Set active attribute to false for audio clients

2015-09-17 Thread Lukas Wunner
The active attribute in struct vga_switcheroo_client denotes whether
the outputs are currently switched to this client. The attribute is
only meaningful for vga clients. It is never used for audio clients.

The function vga_switcheroo_register_audio_client() misuses this
attribute to store whether the audio device is fully initialized.
Most likely there was a misunderstanding about the meaning of
"active" when this was added.

Set the active attribute to false for audio clients. Remove the
active parameter from vga_switcheroo_register_audio_client() and
its sole caller, hda_intel.c:register_vga_switcheroo().

vga_switcheroo_register_audio_client() was introduced by 3e9e63dbd374
("vga_switcheroo: Add the support for audio clients"). Its use in
hda_intel.c was introduced by a82d51ed24bb ("ALSA: hda - Support
VGA-switcheroo").

Cc: Takashi Iwai 
Signed-off-by: Lukas Wunner 
---
 drivers/gpu/vga/vga_switcheroo.c | 5 ++---
 include/linux/vga_switcheroo.h   | 4 ++--
 sound/pci/hda/hda_intel.c| 3 +--
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index b19a72f..fe32536 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -290,7 +290,6 @@ EXPORT_SYMBOL(vga_switcheroo_register_client);
  * @pdev: client pci device
  * @ops: client callbacks
  * @id: client identifier, see enum vga_switcheroo_client_id
- * @active: whether the audio device is fully initialized
  *
  * Register audio client (audio device on a GPU). The power state of the
  * client is assumed to be ON.
@@ -299,9 +298,9 @@ EXPORT_SYMBOL(vga_switcheroo_register_client);
  */
 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 const struct vga_switcheroo_client_ops 
*ops,
-int id, bool active)
+int id)
 {
-   return register_client(pdev, ops, id | ID_BIT_AUDIO, active, false);
+   return register_client(pdev, ops, id | ID_BIT_AUDIO, false, false);
 }
 EXPORT_SYMBOL(vga_switcheroo_register_audio_client);

diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index fe90bfc..3764991 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -128,7 +128,7 @@ int vga_switcheroo_register_client(struct pci_dev *dev,
   bool driver_power_control);
 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 const struct vga_switcheroo_client_ops 
*ops,
-int id, bool active);
+int id);

 void vga_switcheroo_client_fb_set(struct pci_dev *dev,
  struct fb_info *info);
@@ -154,7 +154,7 @@ static inline void vga_switcheroo_client_fb_set(struct 
pci_dev *dev, struct fb_i
 static inline int vga_switcheroo_register_handler(struct 
vga_switcheroo_handler *handler) { return 0; }
 static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
const struct vga_switcheroo_client_ops *ops,
-   int id, bool active) { return 0; }
+   int id) { return 0; }
 static inline void vga_switcheroo_unregister_handler(void) {}
 static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
 static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { 
return VGA_SWITCHEROO_ON; }
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c38c68f..e819013 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1143,8 +1143,7 @@ static int register_vga_switcheroo(struct azx *chip)
 * is there any machine with two switchable HDMI audio controllers?
 */
err = vga_switcheroo_register_audio_client(chip->pci, _vs_ops,
-   VGA_SWITCHEROO_DIS,
-   hda->probe_continued);
+  VGA_SWITCHEROO_DIS);
if (err < 0)
return err;
hda->vga_switcheroo_registered = 1;
-- 
1.8.5.2 (Apple Git-48)



[PATCH 04/15] vga_switcheroo: Add missing locking

2015-09-17 Thread Lukas Wunner
The following functions iterate over the client list, invoke client
callbacks or invoke handler callbacks without locking anything at all:

- Introduced by c8e9cf7bb240 ("vga_switcheroo: Add a helper function to
  get the client state"):
  vga_switcheroo_get_client_state()

- Introduced by 0d69704ae348 ("gpu/vga_switcheroo: add driver control
  power feature. (v3)"):
  vga_switcheroo_set_dynamic_switch()
  vga_switcheroo_runtime_suspend()
  vga_switcheroo_runtime_resume()
  vga_switcheroo_runtime_resume_hdmi_audio()

Refactor vga_switcheroo_runtime_resume_hdmi_audio() a bit to be able to
release vgasr_mutex immediately after iterating over the client list.

Signed-off-by: Lukas Wunner 
---
 drivers/gpu/vga/vga_switcheroo.c | 50 +---
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index fe32536..2138162 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -349,13 +349,18 @@ find_active_client(struct list_head *head)
 int vga_switcheroo_get_client_state(struct pci_dev *pdev)
 {
struct vga_switcheroo_client *client;
+   enum vga_switcheroo_state ret;

+   mutex_lock(_mutex);
client = find_client_from_pci(_priv.clients, pdev);
if (!client)
-   return VGA_SWITCHEROO_NOT_FOUND;
-   if (!vgasr_priv.active)
-   return VGA_SWITCHEROO_INIT;
-   return client->pwr_state;
+   ret = VGA_SWITCHEROO_NOT_FOUND;
+   else if (!vgasr_priv.active)
+   ret = VGA_SWITCHEROO_INIT;
+   else
+   ret = client->pwr_state;
+   mutex_unlock(_mutex);
+   return ret;
 }
 EXPORT_SYMBOL(vga_switcheroo_get_client_state);

@@ -847,15 +852,16 @@ void vga_switcheroo_set_dynamic_switch(struct pci_dev 
*pdev,
 {
struct vga_switcheroo_client *client;

+   mutex_lock(_mutex);
client = find_client_from_pci(_priv.clients, pdev);
-   if (!client)
-   return;
-
-   if (!client->driver_power_control)
+   if (!client || !client->driver_power_control) {
+   mutex_unlock(_mutex);
return;
+   }

client->pwr_state = dynamic;
set_audio_state(client->id, dynamic);
+   mutex_unlock(_mutex);
 }
 EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);

@@ -868,9 +874,11 @@ static int vga_switcheroo_runtime_suspend(struct device 
*dev)
ret = dev->bus->pm->runtime_suspend(dev);
if (ret)
return ret;
+   mutex_lock(_mutex);
if (vgasr_priv.handler->switchto)
vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
+   mutex_unlock(_mutex);
return 0;
 }

@@ -879,7 +887,9 @@ static int vga_switcheroo_runtime_resume(struct device *dev)
struct pci_dev *pdev = to_pci_dev(dev);
int ret;

+   mutex_lock(_mutex);
vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
+   mutex_unlock(_mutex);
ret = dev->bus->pm->runtime_resume(dev);
if (ret)
return ret;
@@ -925,29 +935,33 @@ EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
 static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
 {
struct pci_dev *pdev = to_pci_dev(dev);
+   struct vga_switcheroo_client *client;
+   struct device *video_dev = NULL;
int ret;
-   struct vga_switcheroo_client *client, *found = NULL;

/* we need to check if we have to switch back on the video
   device so the audio device can come back */
+   mutex_lock(_mutex);
list_for_each_entry(client, _priv.clients, list) {
if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) &&
client_is_vga(client)) {
-   found = client;
-   ret = pm_runtime_get_sync(>pdev->dev);
-   if (ret) {
-   if (ret != 1)
-   return ret;
-   }
+   video_dev = >pdev->dev;
break;
}
}
+   mutex_unlock(_mutex);
+
+   if (video_dev) {
+   ret = pm_runtime_get_sync(video_dev);
+   if (ret && ret != 1)
+   return ret;
+   }
ret = dev->bus->pm->runtime_resume(dev);

/* put the reference for the gpu */
-   if (found) {
-   pm_runtime_mark_last_busy(>pdev->dev);
-   pm_runtime_put_autosuspend(>pdev->dev);
+   if (video_dev) {
+   pm_runtime_mark_last_busy(video_dev);
+   pm_runtime_put_autosuspend(video_dev);
}
return ret;
 }
-- 
1.8.5.2 (Apple Git-48)



[PATCH 08/15] vga_switcheroo: Use enum vga_switcheroo_client_id instead of int

2015-09-17 Thread Lukas Wunner
Signed-off-by: Lukas Wunner 
---
 drivers/gpu/vga/vga_switcheroo.c | 17 ++---
 include/linux/vga_switcheroo.h   |  6 +++---
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index bbd0a8e..6e0e705 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -104,7 +104,7 @@ struct vga_switcheroo_client {
struct fb_info *fb_info;
enum vga_switcheroo_state pwr_state;
const struct vga_switcheroo_client_ops *ops;
-   int id;
+   enum vga_switcheroo_client_id id;
bool active;
bool driver_power_control;
struct list_head list;
@@ -235,7 +235,8 @@ EXPORT_SYMBOL(vga_switcheroo_unregister_handler);

 static int register_client(struct pci_dev *pdev,
   const struct vga_switcheroo_client_ops *ops,
-  int id, bool active, bool driver_power_control)
+  enum vga_switcheroo_client_id id, bool active,
+  bool driver_power_control)
 {
struct vga_switcheroo_client *client;

@@ -290,7 +291,7 @@ EXPORT_SYMBOL(vga_switcheroo_register_client);
  * vga_switcheroo_register_audio_client - register audio client
  * @pdev: client pci device
  * @ops: client callbacks
- * @id: client identifier, see enum vga_switcheroo_client_id
+ * @id: client identifier
  *
  * Register audio client (audio device on a GPU). The power state of the
  * client is assumed to be ON.
@@ -299,7 +300,7 @@ EXPORT_SYMBOL(vga_switcheroo_register_client);
  */
 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 const struct vga_switcheroo_client_ops 
*ops,
-int id)
+enum vga_switcheroo_client_id id)
 {
return register_client(pdev, ops, id | ID_BIT_AUDIO, false, false);
 }
@@ -317,7 +318,8 @@ find_client_from_pci(struct list_head *head, struct pci_dev 
*pdev)
 }

 static struct vga_switcheroo_client *
-find_client_from_id(struct list_head *head, int client_id)
+find_client_from_id(struct list_head *head,
+   enum vga_switcheroo_client_id client_id)
 {
struct vga_switcheroo_client *client;

@@ -497,7 +499,8 @@ static int vga_switchoff(struct vga_switcheroo_client 
*client)
return 0;
 }

-static void set_audio_state(int id, enum vga_switcheroo_state state)
+static void set_audio_state(enum vga_switcheroo_client_id id,
+   enum vga_switcheroo_state state)
 {
struct vga_switcheroo_client *client;

@@ -584,7 +587,7 @@ vga_switcheroo_debugfs_write(struct file *filp, const char 
__user *ubuf,
int ret;
bool delay = false, can_switch;
bool just_mux = false;
-   int client_id = VGA_SWITCHEROO_UNKNOWN_ID;
+   enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;
struct vga_switcheroo_client *client = NULL;

if (cnt > 63)
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 664dca5..b2a3dda 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -95,7 +95,7 @@ struct vga_switcheroo_handler {
int (*switchto)(enum vga_switcheroo_client_id id);
int (*power_state)(enum vga_switcheroo_client_id id,
   enum vga_switcheroo_state state);
-   int (*get_client_id)(struct pci_dev *pdev);
+   enum vga_switcheroo_client_id (*get_client_id)(struct pci_dev *pdev);
 };

 /**
@@ -127,7 +127,7 @@ int vga_switcheroo_register_client(struct pci_dev *dev,
   bool driver_power_control);
 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 const struct vga_switcheroo_client_ops 
*ops,
-int id);
+enum vga_switcheroo_client_id id);

 void vga_switcheroo_client_fb_set(struct pci_dev *dev,
  struct fb_info *info);
@@ -153,7 +153,7 @@ static inline void vga_switcheroo_client_fb_set(struct 
pci_dev *dev, struct fb_i
 static inline int vga_switcheroo_register_handler(struct 
vga_switcheroo_handler *handler) { return 0; }
 static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
const struct vga_switcheroo_client_ops *ops,
-   int id) { return 0; }
+   enum vga_switcheroo_client_id id) { return 0; }
 static inline void vga_switcheroo_unregister_handler(void) {}
 static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
 static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct 
pci_dev *dev) { return VGA_SWITCHEROO_ON; }
-- 
1.8.5.2 (Apple Git-48)



[PATCH 07/15] vga_switcheroo: Use VGA_SWITCHEROO_UNKNOWN_ID instead of -1

2015-09-17 Thread Lukas Wunner
Signed-off-by: Lukas Wunner 
---
 drivers/gpu/vga/vga_switcheroo.c | 17 +
 include/linux/vga_switcheroo.h   |  4 
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 7b53246..bbd0a8e 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -86,9 +86,9 @@
  * @fb_info: framebuffer to which console is remapped on switching
  * @pwr_state: current power state
  * @ops: client callbacks
- * @id: client identifier, see enum vga_switcheroo_client_id.
- * Determining the id requires the handler, so GPUs are initially
- * assigned -1 and later given their true id in vga_switcheroo_enable()
+ * @id: client identifier. Determining the id requires the handler,
+ * so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID
+ * and later given their true id in vga_switcheroo_enable()
  * @active: whether the outputs are currently switched to this client
  * @driver_power_control: whether power state is controlled by the driver's
  * runtime pm. If true, writing ON and OFF to the vga_switcheroo debugfs
@@ -147,7 +147,8 @@ struct vgasr_priv {

 #define ID_BIT_AUDIO   0x100
 #define client_is_audio(c) ((c)->id & ID_BIT_AUDIO)
-#define client_is_vga(c)   ((c)->id == -1 || !client_is_audio(c))
+#define client_is_vga(c)   ((c)->id == VGA_SWITCHEROO_UNKNOWN_ID || \
+!client_is_audio(c))
 #define client_id(c)   ((c)->id & ~ID_BIT_AUDIO)

 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
@@ -175,7 +176,7 @@ static void vga_switcheroo_enable(void)
vgasr_priv.handler->init();

list_for_each_entry(client, _priv.clients, list) {
-   if (client->id != -1)
+   if (client->id != VGA_SWITCHEROO_UNKNOWN_ID)
continue;
ret = vgasr_priv.handler->get_client_id(client->pdev);
if (ret < 0)
@@ -279,7 +280,7 @@ int vga_switcheroo_register_client(struct pci_dev *pdev,
   const struct vga_switcheroo_client_ops *ops,
   bool driver_power_control)
 {
-   return register_client(pdev, ops, -1,
+   return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID,
   pdev == vga_default_device(),
   driver_power_control);
 }
@@ -583,7 +584,7 @@ vga_switcheroo_debugfs_write(struct file *filp, const char 
__user *ubuf,
int ret;
bool delay = false, can_switch;
bool just_mux = false;
-   int client_id = -1;
+   int client_id = VGA_SWITCHEROO_UNKNOWN_ID;
struct vga_switcheroo_client *client = NULL;

if (cnt > 63)
@@ -652,7 +653,7 @@ vga_switcheroo_debugfs_write(struct file *filp, const char 
__user *ubuf,
client_id = VGA_SWITCHEROO_DIS;
}

-   if (client_id == -1)
+   if (client_id == VGA_SWITCHEROO_UNKNOWN_ID)
goto out;
client = find_client_from_id(_priv.clients, client_id);
if (!client)
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 219876e..664dca5 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -54,6 +54,9 @@ enum vga_switcheroo_state {

 /**
  * enum vga_switcheroo_client_id - client identifier
+ * @VGA_SWITCHEROO_UNKNOWN_ID: initial identifier assigned to vga clients.
+ * Determining the id requires the handler, so GPUs are given their
+ * true id in a delayed fashion in vga_switcheroo_enable()
  * @VGA_SWITCHEROO_IGD: integrated graphics device
  * @VGA_SWITCHEROO_DIS: discrete graphics device
  * @VGA_SWITCHEROO_MAX_CLIENTS: currently no more than two GPUs are supported
@@ -61,6 +64,7 @@ enum vga_switcheroo_state {
  * Client identifier. Audio clients use the same identifier & 0x100.
  */
 enum vga_switcheroo_client_id {
+   VGA_SWITCHEROO_UNKNOWN_ID = -1,
VGA_SWITCHEROO_IGD,
VGA_SWITCHEROO_DIS,
VGA_SWITCHEROO_MAX_CLIENTS,
-- 
1.8.5.2 (Apple Git-48)



[PATCH 06/15] vga_switcheroo: Use enum vga_switcheroo_state instead of int

2015-09-17 Thread Lukas Wunner
Signed-off-by: Lukas Wunner 
---
 drivers/gpu/vga/vga_switcheroo.c | 6 +++---
 include/linux/vga_switcheroo.h   | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 845e47d..7b53246 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -102,7 +102,7 @@
 struct vga_switcheroo_client {
struct pci_dev *pdev;
struct fb_info *fb_info;
-   int pwr_state;
+   enum vga_switcheroo_state pwr_state;
const struct vga_switcheroo_client_ops *ops;
int id;
bool active;
@@ -346,7 +346,7 @@ find_active_client(struct list_head *head)
  *
  * Return: Power state.
  */
-int vga_switcheroo_get_client_state(struct pci_dev *pdev)
+enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *pdev)
 {
struct vga_switcheroo_client *client;
enum vga_switcheroo_state ret;
@@ -496,7 +496,7 @@ static int vga_switchoff(struct vga_switcheroo_client 
*client)
return 0;
 }

-static void set_audio_state(int id, int state)
+static void set_audio_state(int id, enum vga_switcheroo_state state)
 {
struct vga_switcheroo_client *client;

diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 95bfbeb0..219876e 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -133,7 +133,7 @@ void vga_switcheroo_unregister_handler(void);

 int vga_switcheroo_process_delayed_switch(void);

-int vga_switcheroo_get_client_state(struct pci_dev *dev);
+enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev);

 void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum 
vga_switcheroo_state dynamic);

@@ -152,7 +152,7 @@ static inline int 
vga_switcheroo_register_audio_client(struct pci_dev *pdev,
int id) { return 0; }
 static inline void vga_switcheroo_unregister_handler(void) {}
 static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
-static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { 
return VGA_SWITCHEROO_ON; }
+static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct 
pci_dev *dev) { return VGA_SWITCHEROO_ON; }

 static inline void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, 
enum vga_switcheroo_state dynamic) {}

-- 
1.8.5.2 (Apple Git-48)



[PATCH 02/15] DocBook: Add vga_switcheroo Subsystem Guide

2015-09-17 Thread Lukas Wunner
This is not part of drm.tmpl as vga_switcheroo is a subsystem of its own
which interfaces not just with DRM but also with multiplexer drivers,
ALSA and power management.

Requires Markdown support.

Signed-off-by: Lukas Wunner 
---
 Documentation/DocBook/Makefile|  5 +-
 Documentation/DocBook/vga_switcheroo.tmpl | 92 +++
 2 files changed, 95 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/DocBook/vga_switcheroo.tmpl

diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 8276944..4495b37 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -15,9 +15,10 @@ DOCBOOKS := z8530book.xml device-drivers.xml \
80211.xml debugobjects.xml sh.xml regulator.xml \
alsa-driver-api.xml writing-an-alsa-driver.xml \
tracepoint.xml drm.xml media_api.xml w1.xml \
-   writing_musb_glue_layer.xml crypto-API.xml
+   writing_musb_glue_layer.xml crypto-API.xml \
+   vga_switcheroo.xml

-MARKDOWNREADY := 
+MARKDOWNREADY := vga_switcheroo.xml

 include Documentation/DocBook/media/Makefile

diff --git a/Documentation/DocBook/vga_switcheroo.tmpl 
b/Documentation/DocBook/vga_switcheroo.tmpl
new file mode 100644
index 000..e6128e7
--- /dev/null
+++ b/Documentation/DocBook/vga_switcheroo.tmpl
@@ -0,0 +1,92 @@
+
+http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd; []>
+
+
+  
+vga_switcheroo Subsystem Guide
+
+
+  
+   Lukas
+   Wunner
+   Initial version
+   
+ 
+   lukas at wunner.de
+ 
+   
+  
+
+
+
+  2015
+  Lukas Wunner
+
+
+
+  
+   The contents of this file may be used under the terms of the GNU
+   General Public License version 2 (the "GPL") as distributed in
+   the kernel source COPYING file.
+  
+
+
+
+  
+  
+   1.0
+   2015-08-29
+   LW
+   Initial version
+   
+  
+
+  
+
+
+
+  
+Overview
+!Pdrivers/gpu/vga/vga_switcheroo.c Overview
+  
+
+  
+Modes of Use
+  
+Manual switching and manual power control
+!Pdrivers/gpu/vga/vga_switcheroo.c Manual switching and manual power control
+  
+  
+Driver power control
+!Pdrivers/gpu/vga/vga_switcheroo.c Driver power control
+  
+  
+
+  
+Public functions
+!Edrivers/gpu/vga/vga_switcheroo.c
+  
+
+  
+Public structures
+!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler
+!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_ops
+  
+
+  
+Public constants
+!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id
+!Finclude/linux/vga_switcheroo.h vga_switcheroo_state
+  
+
+  
+Private structures
+!Fdrivers/gpu/vga/vga_switcheroo.c vgasr_priv
+!Fdrivers/gpu/vga/vga_switcheroo.c vga_switcheroo_client
+  
+
+!Cdrivers/gpu/vga/vga_switcheroo.c
+!Cinclude/linux/vga_switcheroo.h
+
+
-- 
1.8.5.2 (Apple Git-48)



[Intel-gfx] [PATCH libdrm] intel: Use CPU mmap for unsynchronized map with linear buffers

2015-09-17 Thread Chris Wilson
On Thu, Sep 17, 2015 at 05:19:02PM +0300, ville.syrjala at linux.intel.com 
wrote:
> From: Ville Syrjälä 
> 
> On LLC platforms there's no need to use GTT mmap for unsynchronized
> maps if the object isn't tiled. So switch to using CPU mmap for linar
> objects. This avoids having to use the GTT for GL buffer objects
> entirely, and thus we can ignore the GTT mappable size limitation.
> For tiled objects we still want the hardware to do the (de)tiling so
> keep using GTT for such objects.
> 
> The display engine is not coherent even on LLC platforms, so this won't
> work too well if we mix scanout and unsynchronized maps of linear bos.
> Actually, that would only be a problem for an already uncached object,
> otherwise it will get clflushed anyway when being made UC/WC prior to
> scanout. The alreday UC object case could be handled by either
> clflushing straight from userspace, or we could add a new ioctl to
> clflush or mark the object as cache_dirty so that it will get
> clflushed in the future just prior to scanout. I started to think
> that a small nop pwrite would have the desired effect, but in fact it
> would only flush the cachelines it touches so wouldn't actually work
> I doubt we want to pwrite the entire object just to get it clflushed.
> 
> This fixes Ilias's arb_texture_buffer_object-max-size piglit test
> on LLC platforms.

Note that there have been patches to fix mesa/i965 for this issue on
both llc and !llc on the mailing list for a few months.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH v2 4/4] drm/msm: Use exynos's model for handling component driver matching.

2015-09-17 Thread Rob Clark
On Thu, Sep 17, 2015 at 10:57 AM, Eric Anholt  wrote:
> This eliminates the need for the "connectors" and "gpus" nodes in the
> devicetree, which we were doing nothing connector- or gpu-specific
> with.

btw, looks pretty good.. hopefully I'll have some time to put my
kernel hat on and test this tomorrow, or worst case next week..

jfwiw, one of my TODO list items that I'm not managing to get around
to is figure out how to make component framework deal w/ nested
sub-components, since dsi-phy is already a subcomponent of dsi (which
is a subcomponent of msm), and we kinda want to split things out
further... but at any rate, this would avoid all the
noncomponent_drivers nonsense.  Anyways, not sure if this is something
other drivers need too, if so let me know and I'll CC you on patches
when I eventually get around to that..

BR,
-R

> Signed-off-by: Eric Anholt 
> ---
>  drivers/gpu/drm/msm/msm_drv.c | 65 
> +--
>  include/drm/drmP.h|  2 +-
>  2 files changed, 27 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index a9b0573..4e1263b 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -1039,34 +1039,7 @@ static const struct dev_pm_ops msm_pm_ops = {
>   * Componentized driver support:
>   */
>
> -#ifdef CONFIG_OF
> -/* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx
> - * (or probably any other).. so probably some room for some helpers
> - */
> -static int compare_of(struct device *dev, void *data)
> -{
> -   return dev->of_node == data;
> -}
> -
> -static int add_components(struct device *dev, struct component_match 
> **matchptr,
> -   const char *name)
> -{
> -   struct device_node *np = dev->of_node;
> -   unsigned i;
> -
> -   for (i = 0; ; i++) {
> -   struct device_node *node;
> -
> -   node = of_parse_phandle(np, name, i);
> -   if (!node)
> -   break;
> -
> -   component_match_add(dev, matchptr, compare_of, node);
> -   }
> -
> -   return 0;
> -}
> -#else
> +#ifndef CONFIG_OF
>  static int compare_dev(struct device *dev, void *data)
>  {
> return dev == data;
> @@ -1088,6 +1061,20 @@ static const struct component_master_ops msm_drm_ops = 
> {
> .unbind = msm_drm_unbind,
>  };
>
> +static struct platform_driver *const noncomponent_drivers[] = {
> +#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
> +   _dsi_phy_driver,
> +#endif
> +};
> +
> +static struct platform_driver *const component_drivers[] = {
> +#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
> +   _dsi_driver,
> +#endif
> +   _hdmi_driver,
> +   _driver,
> +};
> +
>  /*
>   * Platform driver:
>   */
> @@ -1096,8 +1083,9 @@ static int msm_pdev_probe(struct platform_device *pdev)
>  {
> struct component_match *match = NULL;
>  #ifdef CONFIG_OF
> -   add_components(>dev, , "connectors");
> -   add_components(>dev, , "gpus");
> +   drm_platform_component_match_add_drivers(>dev, ,
> +component_drivers,
> +
> ARRAY_SIZE(component_drivers));
>  #else
> /* For non-DT case, it kinda sucks.  We don't actually have a way
>  * to know whether or not we are waiting for certain devices (or if
> @@ -1159,20 +1147,17 @@ static struct platform_driver msm_platform_driver = {
> .id_table   = msm_id,
>  };
>
> -static struct platform_driver *const component_drivers[] = {
> -#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
> -   _dsi_phy_driver,
> -   _dsi_driver,
> -#endif
> -   _hdmi_driver,
> -   _driver,
> -};
> -
>  static int __init msm_drm_register(void)
>  {
> int ret;
>
> DBG("init");
> +
> +   ret = drm_platform_register_drivers(noncomponent_drivers,
> +   ARRAY_SIZE(noncomponent_drivers));
> +   if (ret)
> +   return ret;
> +
> ret = drm_platform_register_drivers(component_drivers,
> ARRAY_SIZE(component_drivers));
> if (ret)
> @@ -1187,6 +1172,8 @@ static void __exit msm_drm_unregister(void)
> platform_driver_unregister(_platform_driver);
> drm_platform_unregister_drivers(component_drivers,
> ARRAY_SIZE(component_drivers));
> +   drm_platform_unregister_drivers(noncomponent_drivers,
> +   ARRAY_SIZE(noncomponent_drivers));
>  }
>
>  module_init(msm_drm_register);
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index b65d886..0da8599 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -1094,7 +1094,7 @@ void drm_platform_unregister_drivers(struct 
> platform_driver *const *drv,
>  int count);
>  void drm_platform_component_match_add_drivers(struct 

[PATCH 01/15] vga_switcheroo: Document _ALL_ the things!

2015-09-17 Thread Danilo Cesar Lemes de Paula
On 09/17/2015 02:31 PM, Lukas Wunner wrote:
> Hi Danilo,
> 
> On Thu, Sep 17, 2015 at 01:34:54PM -0300, Danilo Cesar Lemes de Paula wrote:
>>> - * GPU driver interface
>>> - * - set_gpu_state - this should do the equiv of s/r for the card
>>> - * - this should *not* set the discrete power state
>>
>> Did you check if this creates the desired format? (ie: Doesn't create a
>>  block).
> 
> These lines are deleted by the patch.

Sorry, you're totally right.

> 
> One oddity I did notice however is that in the HTML documentation for the
> public function vga_switcheroo_process_delayed_switch(), instead of the
> heading "Description" it says "Manual switching and manual power control"
> (which is the identifier of the preceding DOC section). I guess it's a bug
> in kernel-doc but I couldn't be bothered so far to look into it. No idea
> if it's introduced by your patches or if it was there all along.

That's odd... But I can have a look later.

> 
> Another thing I noticed is that URLs are not clickable in the HTML output.

Did you tried the correct format? I just saw a regular http string,
which won't be converted. Markdown has this not obvious format for
links: This is a [Google](http://google.com) link

http://pandoc.org/try/?text=sudo+give+me+a+[link]%28http%3A%2F%2Fkernel.org%29%0A=markdown=docbook

> 
> Otherwise the markdown support works great (though I've only used it for
> unsorted lists in this documentation).
> 
> Thanks,
> 
> Lukas
> 

Danilo Cesar


[RFC 0/2] drm/dsi: DSI for devices with different control bus

2015-09-17 Thread Archit Taneja


On 9/15/2015 9:13 PM, Rob Herring wrote:
> On 09/15/2015 05:32 AM, Archit Taneja wrote:
>> Hi Rob, Mark,
>>
>> We've been trying to figure out the right way to represent a class
>> of display encoder devices in DT.
>
> I've been meaning to reply on this.
>
>> These devices have registers that are generally configured via i2c. Once
>> the device is configured, it takes in video data from the mipi
>> dsi bus.
>>
>> Until now, all the devices we've supported devices that can be are
>> configured by the dsi bus itself, and hence, we've been able to
>> represent them in DT as children under the dsi host.
>>
>> For the above class of devices (using both i2c and dsi), we aren't
>> able to conclude upon what's the better approach among the two:
>>
>> 1. Represent the device via 2 different nodes in DT. One would be
>> a child under an i2c adapter, the other a child of a dsi host. We
>> would have two device drivers, one i2c client, and the other a
>> mipi dsi device.
>>
>> 2. Represent the device as an i2c client in DT. Provide an api
>> to create "dummy" dsi devices. The i2c client driver would use
>> this api to register a dsi device, and link itself with the dsi
>> host.
>>
>> What do you think would be the way to go here? I guess you
>> might have faced something similar in other subsystems.
>
> The closest thing I can think of are WiFi/BT combo chips that use
> SDIO+UART. In that case, 2 nodes makes sense as these chips are
> essentially 2 independent functions in a single chip and both interfaces
> are control interfaces (as well as data). This case is a bit different
> with both interfaces being tied to the same function.
>
> So in this case, I think option 2 is the right way for the reasons
> already outlined in this thread. I think there needs to be more
> consistency in how the of-graph connections are defined with the core
> doing more of the graph traversing. So having an i2c device plus
> of-graph seems more consistent with other non-DSI cases.
>
> The main open issue seemed to be setting the VC. At least for the
> ADV7533, it can be whatever you want it to be. The host and device just
> need to agree. I see no need for that to be in DT at least in this case.
> But then I'm not sure what are typical constraints for VC assignment.
> I'd guess that constraints are on the device side and hosts can support
> whatever the device wants. If so, then it can purely be up to the driver
> to set.

2 DSI devices connected to the same host shouldn't have the same VC.
When representing the DSI nodes via DT, we use the 'reg' property to
assign the VC.

Although, in practice, we don't generally have multiple devices
on the same bus. The trend is to have multiple DSI hosts on the
platform to support more devices.

If we have checks that ensures the DT way and the new manual way
of creation of DSI devices doesn't result in having conflicting VCs
for devices, we should be okay.

>
> Implementation-wise, I don't think that I'd call this a dummy device.
> There are multiple ways for devices to get created in the driver model.
> DT is just one way. You are just creating the device in a different way
> outside of DT which is fine.
>

Thanks for the feedback.

Archit

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


[patch 4/4] drm/qxl: integer overflow in qxl_alloc_surf_ioctl()

2015-09-17 Thread Dan Carpenter
The size calculation can overflow.

Signed-off-by: Dan Carpenter 

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index 552dc06..5da9a60 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -401,6 +401,8 @@ static int qxl_alloc_surf_ioctl(struct drm_device *dev, 
void *data,

/* work out size allocate bo with handle */
actual_stride = param->stride < 0 ? -param->stride : param->stride;
+   if (actual_stride > (INT_MAX - actual_stride) / param->height)
+   return -EINVAL;
size = actual_stride * param->height + actual_stride;

surf.format = param->format;


[patch 3/4] drm/qxl: array underflow in qxl_clientcap_ioctl()

2015-09-17 Thread Dan Carpenter
We check that "byte" isn't writing beyond the end of the array but we
also need to prevent array underflow.

Signed-off-by: Dan Carpenter 

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index b2db482..552dc06 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -372,7 +372,7 @@ static int qxl_clientcap_ioctl(struct drm_device *dev, void 
*data,
 {
struct qxl_device *qdev = dev->dev_private;
struct drm_qxl_clientcap *param = data;
-   int byte, idx;
+   unsigned int byte, idx;

byte = param->index / 8;
idx = param->index % 8;


[patch 2/4] drm/qxl: potential NULL dereference in apply_reloc()

2015-09-17 Thread Dan Carpenter
qxl_bo_kmap_atomic_page() can fail.  I think the user controls
->dst_offset so this can be used to corrupt memory.

Signed-off-by: Dan Carpenter 

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index eda6f30..b2db482 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -86,6 +86,8 @@ apply_reloc(struct qxl_device *qdev, struct qxl_reloc_info 
*info)
 {
void *reloc_page;
reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, 
info->dst_offset & PAGE_MASK);
+   if (!reloc_page)
+   return;
*(uint64_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = 
qxl_bo_physical_address(qdev,

  info->src_bo,

  info->src_offset);


[patch 1/4] drm/qxl: integer overflow in qxl_process_single_command()

2015-09-17 Thread Dan Carpenter
This size calculation can overflow on 32 bit systems leading to memory
corruption.

Reported-by: Ilja Van Sprundel 
Signed-off-by: Dan Carpenter 

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index bda5c5f..eda6f30 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -168,7 +168,7 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
   cmd->command_size))
return -EFAULT;

-   reloc_info = kmalloc(sizeof(struct qxl_reloc_info) * cmd->relocs_num, 
GFP_KERNEL);
+   reloc_info = kmalloc_array(cmd->relocs_num, sizeof(struct 
qxl_reloc_info), GFP_KERNEL);
if (!reloc_info)
return -ENOMEM;



[PATCH] drm/vmwgfx: fix return of garbage

2015-09-17 Thread Sudip Mukherjee
Incase of error we printed the error message and returned ret. But ret
was never initialized and so we have been returning garbage value on
error.

Signed-off-by: Sudip Mukherjee 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 61fb7f3..43ed33f1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1685,7 +1685,6 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
struct drm_crtc *crtc;
u32 num_units = 0;
u32 i, k;
-   int ret;

dirty->dev_priv = dev_priv;

@@ -1711,7 +1710,7 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
if (!dirty->cmd) {
DRM_ERROR("Couldn't reserve fifo space "
  "for dirty blits.\n");
-   return ret;
+   return -EIO;
}
memset(dirty->cmd, 0, dirty->fifo_reserve_size);
}
-- 
1.9.1



[PATCH 01/15] vga_switcheroo: Document _ALL_ the things!

2015-09-17 Thread Danilo Cesar Lemes de Paula
On 08/23/2015 10:18 AM, Lukas Wunner wrote:
> This adds an "Overview" DOC section plus two DOC sections for the modes
> of use ("Manual switching and manual power control" and "Driver power
> control").
> 
> Also included is kernel-doc for all public functions, structs and enums.

Regarding the markdown support, it does makes sense.
Just a small comment in the middle to be sure that required effect is
achieved.


Danilo Cesar


>
> Signed-off-by: Lukas Wunner 
> ---
>  drivers/gpu/vga/vga_switcheroo.c | 285 
> +--
>  include/linux/vga_switcheroo.h   |  85 +++-
>  2 files changed, 353 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/vga/vga_switcheroo.c 
> b/drivers/gpu/vga/vga_switcheroo.c
> index 2106066..b19a72f 100644
> --- a/drivers/gpu/vga/vga_switcheroo.c
> +++ b/drivers/gpu/vga/vga_switcheroo.c
> @@ -1,20 +1,31 @@
>  /*
> + * vga_switcheroo.c - Support for laptop with dual GPU using one set of 
> outputs
> + *
>   * Copyright (c) 2010 Red Hat Inc.
>   * Author : Dave Airlie 
>   *
> + * Copyright (c) 2015 Lukas Wunner 
>   *
> - * Licensed under GPLv2
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
>   *
> - * vga_switcheroo.c - Support for laptop with dual GPU using one set of 
> outputs
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
>   *
> - * Switcher interface - methods require for ATPX and DCM
> - * - switchto - this throws the output MUX switch
> - * - discrete_set_power - sets the power state for the discrete card
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS
> + * IN THE SOFTWARE.
>   *
> - * GPU driver interface
> - * - set_gpu_state - this should do the equiv of s/r for the card
> - * - this should *not* set the discrete power state

Did you check if this creates the desired format? (ie: Doesn't create a
 block).

> - * - switch_check  - check if the device is in a position to switch now
>   */
>  
>  #define pr_fmt(fmt) "vga_switcheroo: " fmt
> @@ -33,6 +44,61 @@
>  
>  #include 
>  
> +/**
> + * DOC: Overview
> + *
> + * vga_switcheroo is the Linux subsystem for laptop hybrid graphics.
> + * These come in two flavors:
> + *
> + * * muxed: Dual GPUs with a multiplexer chip to switch outputs between GPUs.
> + * * muxless: Dual GPUs but only one of them is connected to outputs.
> + *   The other one is merely used to offload rendering, its results
> + *   are copied over PCIe into the framebuffer. On Linux this is
> + *   supported with DRI PRIME.
> + *
> + * Hybrid graphics started to appear in the late Naughties and were initially
> + * all muxed. Newer laptops moved to a muxless architecture for cost reasons.
> + * A notable exception is the MacBook Pro which continues to use a mux.
> + * Muxes come with varying capabilities: Some switch only the panel, others
> + * can also switch external displays. Some switch all display pins at once
> + * while others can switch just the DDC lines. (To allow EDID probing
> + * for the inactive GPU.) Also, muxes are often used to cut power to the
> + * discrete GPU while it is not used.
> + *
> + * DRM drivers register GPUs with vga_switcheroo, these are heretoforth 
> called
> + * clients. The mux is called the handler. Muxless machines also register a
> + * handler to control the power state of the discrete GPU, its ->switchto
> + * callback is a no-op for obvious reasons. The discrete GPU is often 
> equipped
> + * with an HDA controller for the HDMI/DP audio signal, this will also
> + * register as a client so that vga_switcheroo can take care of the correct
> + * suspend/resume order when changing the discrete GPU's power state. In 
> total
> + * there can thus be up to three clients: Two vga clients (GPUs) and one 
> audio
> + * client (on the discrete GPU). The code is mostly prepared to support
> + * machines with more than two GPUs should they become available.
> + * The GPU to which the outputs are currently switched is called the
> + * active client in vga_switcheroo parlance. The GPU not in use 

[PATCH v2 4/4] drm/msm: Use exynos's model for handling component driver matching.

2015-09-17 Thread Eric Anholt
This eliminates the need for the "connectors" and "gpus" nodes in the
devicetree, which we were doing nothing connector- or gpu-specific
with.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/msm/msm_drv.c | 65 +--
 include/drm/drmP.h|  2 +-
 2 files changed, 27 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index a9b0573..4e1263b 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1039,34 +1039,7 @@ static const struct dev_pm_ops msm_pm_ops = {
  * Componentized driver support:
  */

-#ifdef CONFIG_OF
-/* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx
- * (or probably any other).. so probably some room for some helpers
- */
-static int compare_of(struct device *dev, void *data)
-{
-   return dev->of_node == data;
-}
-
-static int add_components(struct device *dev, struct component_match 
**matchptr,
-   const char *name)
-{
-   struct device_node *np = dev->of_node;
-   unsigned i;
-
-   for (i = 0; ; i++) {
-   struct device_node *node;
-
-   node = of_parse_phandle(np, name, i);
-   if (!node)
-   break;
-
-   component_match_add(dev, matchptr, compare_of, node);
-   }
-
-   return 0;
-}
-#else
+#ifndef CONFIG_OF
 static int compare_dev(struct device *dev, void *data)
 {
return dev == data;
@@ -1088,6 +1061,20 @@ static const struct component_master_ops msm_drm_ops = {
.unbind = msm_drm_unbind,
 };

+static struct platform_driver *const noncomponent_drivers[] = {
+#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
+   _dsi_phy_driver,
+#endif
+};
+
+static struct platform_driver *const component_drivers[] = {
+#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
+   _dsi_driver,
+#endif
+   _hdmi_driver,
+   _driver,
+};
+
 /*
  * Platform driver:
  */
@@ -1096,8 +1083,9 @@ static int msm_pdev_probe(struct platform_device *pdev)
 {
struct component_match *match = NULL;
 #ifdef CONFIG_OF
-   add_components(>dev, , "connectors");
-   add_components(>dev, , "gpus");
+   drm_platform_component_match_add_drivers(>dev, ,
+component_drivers,
+ARRAY_SIZE(component_drivers));
 #else
/* For non-DT case, it kinda sucks.  We don't actually have a way
 * to know whether or not we are waiting for certain devices (or if
@@ -1159,20 +1147,17 @@ static struct platform_driver msm_platform_driver = {
.id_table   = msm_id,
 };

-static struct platform_driver *const component_drivers[] = {
-#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
-   _dsi_phy_driver,
-   _dsi_driver,
-#endif
-   _hdmi_driver,
-   _driver,
-};
-
 static int __init msm_drm_register(void)
 {
int ret;

DBG("init");
+
+   ret = drm_platform_register_drivers(noncomponent_drivers,
+   ARRAY_SIZE(noncomponent_drivers));
+   if (ret)
+   return ret;
+
ret = drm_platform_register_drivers(component_drivers,
ARRAY_SIZE(component_drivers));
if (ret)
@@ -1187,6 +1172,8 @@ static void __exit msm_drm_unregister(void)
platform_driver_unregister(_platform_driver);
drm_platform_unregister_drivers(component_drivers,
ARRAY_SIZE(component_drivers));
+   drm_platform_unregister_drivers(noncomponent_drivers,
+   ARRAY_SIZE(noncomponent_drivers));
 }

 module_init(msm_drm_register);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index b65d886..0da8599 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1094,7 +1094,7 @@ void drm_platform_unregister_drivers(struct 
platform_driver *const *drv,
 int count);
 void drm_platform_component_match_add_drivers(struct device *dev,
  struct component_match **match,
- struct platform_driver **drivers,
+ struct platform_driver *const 
*drivers,
  int count);

 /* returns true if currently okay to sleep */
-- 
2.1.4



[PATCH v2 3/4] drm: Move exynos "match_add all devices matching my drivers" to core.

2015-09-17 Thread Eric Anholt
This is a really nice way to handle the component setup.  The
subsystem driver knows that it's got a bunch of component drivers, and
for any devices that matched its component drivers, it wants all of
those to bind to it as master.

Signed-off-by: Eric Anholt 
---

v2: Extend the kerneldoc.

 drivers/gpu/drm/drm_platform_helper.c   | 40 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 37 ++
 include/drm/drmP.h  |  5 +
 3 files changed, 52 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/drm_platform_helper.c 
b/drivers/gpu/drm/drm_platform_helper.c
index 450846f..c4f03541 100644
--- a/drivers/gpu/drm/drm_platform_helper.c
+++ b/drivers/gpu/drm/drm_platform_helper.c
@@ -7,6 +7,7 @@
  * option) any later version.
  */

+#include 
 #include 

 /**
@@ -51,3 +52,42 @@ void drm_platform_unregister_drivers(struct platform_driver 
*const *drv,
platform_driver_unregister(drv[count]);
 }
 EXPORT_SYMBOL_GPL(drm_platform_unregister_drivers);
+
+static int compare_dev(struct device *dev, void *data)
+{
+   return dev == (struct device *)data;
+}
+
+/**
+ * drm_platform_component_match_add_drivers - For each driver passed
+ * in, finds each device that probed with it and adds it as a component
+ * driver to the match list.
+ * @dev: master device for the components
+ * @match:   pointer to the match structure pointer.  For the first
+ *   component_match_add(), this should be a pointer to a NULL
+ *   pointer, which will get filled in by the call.
+ * @drivers: array of platform drivers whose devices should all be
+ *   added to the match
+ * @count:   number of platform drivers to match
+ */
+void drm_platform_component_match_add_drivers(struct device *dev,
+ struct component_match **match,
+ struct platform_driver *const 
*drivers,
+ int count)
+{
+   int i;
+
+   for (i = 0; i < count; i++) {
+   struct device_driver *drv = [i]->driver;
+   struct device *p = NULL, *d;
+
+   while ((d = bus_find_device(_bus_type, p, drv,
+   (void *)platform_bus_type.match))) {
+   put_device(p);
+   component_match_add(dev, match, compare_dev, d);
+   p = d;
+   }
+   put_device(p);
+   }
+}
+EXPORT_SYMBOL_GPL(drm_platform_component_match_add_drivers);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 83f829b..9151304 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -412,32 +412,6 @@ static struct platform_driver *const 
exynos_drm_drv_with_simple_dev[] = {
 };
 #define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)

-static int compare_dev(struct device *dev, void *data)
-{
-   return dev == (struct device *)data;
-}
-
-static struct component_match *exynos_drm_match_add(struct device *dev)
-{
-   struct component_match *match = NULL;
-   int i;
-
-   for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
-   struct device_driver *drv = _drm_kms_drivers[i]->driver;
-   struct device *p = NULL, *d;
-
-   while ((d = bus_find_device(_bus_type, p, drv,
-   (void *)platform_bus_type.match))) {
-   put_device(p);
-   component_match_add(dev, , compare_dev, d);
-   p = d;
-   }
-   put_device(p);
-   }
-
-   return match ?: ERR_PTR(-ENODEV);
-}
-
 static int exynos_drm_bind(struct device *dev)
 {
return drm_platform_init(_drm_driver, to_platform_device(dev));
@@ -455,14 +429,17 @@ static const struct component_master_ops exynos_drm_ops = 
{

 static int exynos_drm_platform_probe(struct platform_device *pdev)
 {
-   struct component_match *match;
+   struct component_match *match = NULL;

pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);

-   match = exynos_drm_match_add(>dev);
-   if (IS_ERR(match))
-   return PTR_ERR(match);
+   drm_platform_component_match_add_drivers(>dev, ,
+exynos_drm_kms_drivers,
+
ARRAY_SIZE(exynos_drm_kms_drivers));
+
+   if (!match)
+   return -ENODEV;

return component_master_add_with_match(>dev, _drm_ops,
   match);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index a774574..b65d886 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -88,6 +88,7 @@ struct device_node;
 struct videomode;
 

[PATCH v2 2/4] drm/msm: Use drm_platform_register/unregister_drivers().

2015-09-17 Thread Eric Anholt
This matches how exynos handles the registration of its component
drivers.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 12 +---
 drivers/gpu/drm/msm/dsi/dsi.c  | 16 +---
 drivers/gpu/drm/msm/dsi/dsi.h  |  2 --
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c  | 12 +---
 drivers/gpu/drm/msm/edp/edp.c  | 14 +-
 drivers/gpu/drm/msm/hdmi/hdmi.c| 12 +---
 drivers/gpu/drm/msm/msm_drv.c  | 26 ++
 drivers/gpu/drm/msm/msm_drv.h  | 16 
 drivers/gpu/drm/msm/msm_gpu.h  |  3 +--
 9 files changed, 28 insertions(+), 85 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 1ea2df5..8b0eb95 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -286,7 +286,7 @@ static const struct of_device_id dt_match[] = {
{}
 };

-static struct platform_driver adreno_driver = {
+struct platform_driver adreno_driver = {
.probe = adreno_probe,
.remove = adreno_remove,
.driver = {
@@ -294,13 +294,3 @@ static struct platform_driver adreno_driver = {
.of_match_table = dt_match,
},
 };
-
-void __init adreno_register(void)
-{
-   platform_driver_register(_driver);
-}
-
-void __exit adreno_unregister(void)
-{
-   platform_driver_unregister(_driver);
-}
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 6edcd6f..41cfbd5 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -163,7 +163,7 @@ static const struct of_device_id dt_match[] = {
{}
 };

-static struct platform_driver dsi_driver = {
+struct platform_driver msm_dsi_driver = {
.probe = dsi_dev_probe,
.remove = dsi_dev_remove,
.driver = {
@@ -172,20 +172,6 @@ static struct platform_driver dsi_driver = {
},
 };

-void __init msm_dsi_register(void)
-{
-   DBG("");
-   msm_dsi_phy_driver_register();
-   platform_driver_register(_driver);
-}
-
-void __exit msm_dsi_unregister(void)
-{
-   DBG("");
-   msm_dsi_phy_driver_unregister();
-   platform_driver_unregister(_driver);
-}
-
 int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM])
 {
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 5f5a373..08fff5c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -164,8 +164,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi);

 /* dsi phy */
 struct msm_dsi_phy;
-void msm_dsi_phy_driver_register(void);
-void msm_dsi_phy_driver_unregister(void);
 int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
const unsigned long bit_rate, const unsigned long esc_rate);
 void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c 
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 401ff58..f918b56 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -375,7 +375,7 @@ static int dsi_phy_driver_remove(struct platform_device 
*pdev)
return 0;
 }

-static struct platform_driver dsi_phy_platform_driver = {
+struct platform_driver msm_dsi_phy_driver = {
.probe  = dsi_phy_driver_probe,
.remove = dsi_phy_driver_remove,
.driver = {
@@ -384,16 +384,6 @@ static struct platform_driver dsi_phy_platform_driver = {
},
 };

-void __init msm_dsi_phy_driver_register(void)
-{
-   platform_driver_register(_phy_platform_driver);
-}
-
-void __exit msm_dsi_phy_driver_unregister(void)
-{
-   platform_driver_unregister(_phy_platform_driver);
-}
-
 int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
const unsigned long bit_rate, const unsigned long esc_rate)
 {
diff --git a/drivers/gpu/drm/msm/edp/edp.c b/drivers/gpu/drm/msm/edp/edp.c
index 0940e84..0bf75b0 100644
--- a/drivers/gpu/drm/msm/edp/edp.c
+++ b/drivers/gpu/drm/msm/edp/edp.c
@@ -122,7 +122,7 @@ static const struct of_device_id dt_match[] = {
{}
 };

-static struct platform_driver edp_driver = {
+struct platform_driver msm_edp_driver = {
.probe = edp_dev_probe,
.remove = edp_dev_remove,
.driver = {
@@ -131,18 +131,6 @@ static struct platform_driver edp_driver = {
},
 };

-void __init msm_edp_register(void)
-{
-   DBG("");
-   platform_driver_register(_driver);
-}
-
-void __exit msm_edp_unregister(void)
-{
-   DBG("");
-   platform_driver_unregister(_driver);
-}
-
 /* Second part of initialization, the drm/kms level modeset_init */
 int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev,
struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c 

[PATCH v2 1/4] drm: Put platform driver registration/unregistration loops in core.

2015-09-17 Thread Eric Anholt
This is mostly just a move of the code from exynos, with a slight
reformat.  I wanted to do a similar thing for vc4, and msm looks like
a good candidate as well.

Signed-off-by: Eric Anholt 
---

v2: Move to the KMS helper config flag, and add our kerneldoc to
drm.tmpl (under the "Driver Initialization" section), as requested
by danvet.  Move to drm_platform_helper.c instead of _helpers.c to
be consistent with other files.

 Documentation/DocBook/drm.tmpl  |  4 +++
 drivers/gpu/drm/Makefile|  3 +-
 drivers/gpu/drm/drm_platform_helper.c   | 53 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 38 ---
 include/drm/drmP.h  |  4 +++
 5 files changed, 69 insertions(+), 33 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_platform_helper.c

diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 9ddf8c6..1678d8f 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -465,6 +465,10 @@ char *date;
 
   
 
+
+  Platform Helper Functions Reference
+!Edrivers/gpu/drm/drm_platform_helper.c
+
   

   
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 45e7719..8e3f251 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -21,7 +21,8 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o
 drm-$(CONFIG_OF) += drm_of.o

 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
-   drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
+   drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
+   drm_platform_helper.o
 drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
diff --git a/drivers/gpu/drm/drm_platform_helper.c 
b/drivers/gpu/drm/drm_platform_helper.c
new file mode 100644
index 000..450846f
--- /dev/null
+++ b/drivers/gpu/drm/drm_platform_helper.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+
+/**
+ * drm_platform_register_drivers - Helper to register an array of
+ * struct platform_drivers wth platform_driver_register().
+ * @drv:   array of platform drivers to register
+ * @count: number of drivers in the array
+ *
+ * Use drm_platform_unregister_drivers() to undo this.
+ *
+ * Return: 0 on success, -errno value from the last
+ * platform_driver_register otherwise.
+ */
+int drm_platform_register_drivers(struct platform_driver *const *drv,
+ int count)
+{
+   int i, ret;
+
+   for (i = 0; i < count; ++i) {
+   ret = platform_driver_register(drv[i]);
+   if (ret) {
+   while (--i >= 0)
+   platform_driver_unregister(drv[i]);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(drm_platform_register_drivers);
+
+/**
+ * drm_platform_unregister_drivers - Helper to unregister an array of
+ * struct platform_drivers.
+ * @drv:   array of platform drivers to unregister
+ * @count: number of drivers in the array
+ */
+void drm_platform_unregister_drivers(struct platform_driver *const *drv,
+int count)
+{
+   while (--count >= 0)
+   platform_driver_unregister(drv[count]);
+}
+EXPORT_SYMBOL_GPL(drm_platform_unregister_drivers);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index fa5194c..83f829b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -520,53 +520,27 @@ static int exynos_drm_register_devices(void)
return 0;
 }

-static void exynos_drm_unregister_drivers(struct platform_driver * const *drv,
- int count)
-{
-   while (--count >= 0)
-   platform_driver_unregister(drv[count]);
-}
-
-static int exynos_drm_register_drivers(struct platform_driver * const *drv,
-  int count)
-{
-   int i, ret;
-
-   for (i = 0; i < count; ++i) {
-   ret = platform_driver_register(drv[i]);
-   if (!ret)
-   continue;
-
-   while (--i >= 0)
-   platform_driver_unregister(drv[i]);
-
-   return ret;
-   }
-
-   return 0;
-}
-
 static inline int exynos_drm_register_kms_drivers(void)
 {
-   return exynos_drm_register_drivers(exynos_drm_kms_drivers,
-   

[PATCH] drm/mgag200: Fix calling drm_fb_helper_fini() twice

2015-09-17 Thread Ingo Molnar

* Ingo Molnar  wrote:

> So this patch was whitespace damaged - I applied it by hand and made the 
> commit 
> below. This has solved the crash, thanks Archit!

Spoke too soon - the attached (allyesconfig-ish) config still crashes, first 
there 
are a handful of kobject debug warnings, then:

[  115.274847] [drm:mgag200_mm_init] *ERROR* Failed setting up TTM memory 
accounting subsystem.
[  115.274853] BUG: unable to handle kernel NULL pointer dereference at 
  (null)
[  115.274856] IP: [] drm_mode_config_cleanup+0x1f/0x1cc
[  115.274858] PGD 0 
[  115.274860] Oops:  [#1] SMP DEBUG_PAGEALLOC KASAN
[  115.274861] Modules linked in:
[  115.274862] CPU: 0 PID: 4 Comm: kworker/0:0 Tainted: GWL  
4.3.0-rc1-01729-g525850e-dirty #59
[  115.274863] Hardware name: Intel Corporation S2600GZ/S2600GZ, BIOS 
SE5C600.86B.02.02.0002.122320131210 12/23/2013
[  115.274865] Workqueue: events work_for_cpu_fn
[  115.274865] task: 88017d2a8000 ti: 88017d2b task.ti: 
88017d2b
[  115.274868] RIP: 0010:[]  [] 
drm_mode_config_cleanup+0x1f/0x1cc
[  115.274868] RSP: :88017d2b7bd8  EFLAGS: 00010246
[  115.274869] RAX:  RBX: 8800ba0a4520 RCX: 81186ff1
[  115.274870] RDX: 88017d2b7a90 RSI: 83d73579 RDI: 8800ba0a4520
[  115.274870] RBP: 88017d2b7bf0 R08: 0001 R09: 
[  115.274871] R10: 00075000 R11: 85147a82 R12: 8800ba0a4520
[  115.274872] R13: 8800ba0a4da8 R14: fffe R15: 8800ba0a3400
[  115.274873] FS:  () GS:880420e0() 
knlGS:
[  115.274874] CS:  0010 DS:  ES:  CR0: 80050033
[  115.274875] CR2:  CR3: 05e2d000 CR4: 001406f0
[  115.274876] Stack:
[  115.274877]  8800ba0a3400 8800ba0a4520 fffe 
88017d2b7c10
[  115.274879]  81cb6a3e 8800ba0a4520 8800ba0a3400 
88017d2b7c78
[  115.274881]  81cb6efe 07200100 aa55 
075b
[  115.274881] Call Trace:
[  115.274883]  [] mgag200_driver_unload+0x30/0x48
[  115.274884]  [] mgag200_driver_load+0x4a8/0x4ba
[  115.274886]  [] drm_dev_register+0x6f/0xb0
[  115.274887]  [] drm_get_pci_dev+0xff/0x1c2
[  115.274889]  [] mga_pci_probe+0xa6/0xad
[  115.274890]  [] local_pci_probe+0x3d/0x82
[  115.274891]  [] work_for_cpu_fn+0x14/0x1b
[  115.274893]  [] process_one_work+0x28e/0x4ef
[  115.274895]  [] ? process_one_work+0x170/0x4ef
[  115.274897]  [] process_scheduled_works+0x21/0x2f

Full log is below, config attached as well.

Thanks,

Ingo

>
[  115.243547] mgag200 :0b:00.0: no default pinctrl state
[  115.243732] devices_kset: Moving :0b:00.0 to end of list
[  115.247078] device: 'controlD64': device_add
[  115.247494] PM: Adding info for No Bus:controlD64
[  115.247979] device: 'card0': device_add
[  115.248315] PM: Adding info for No Bus:card0
[  115.274511] [ cut here ]
[  115.274518] WARNING: CPU: 0 PID: 4 at lib/kobject.c:582 
kobject_get+0x33/0x6a()
[  115.274519] kobject: 'ttm' (86c28700): is not initialized, yet 
kobject_get() is being called.
[  115.274521] Modules linked in:
[  115.274524] CPU: 0 PID: 4 Comm: kworker/0:0 Tainted: GWL  
4.3.0-rc1-01729-g525850e-dirty #59
[  115.274525] Hardware name: Intel Corporation S2600GZ/S2600GZ, BIOS 
SE5C600.86B.02.02.0002.122320131210 12/23/2013
[  115.274529] Workqueue: events work_for_cpu_fn
[  115.274532]   88017d2b79a8 8188f38b 
88017d2b79f0
[  115.274534]  88017d2b79e0 81144593 8189129f 
86c28700
[  115.274536]   86c28700 007f4000 
88017d2b7a40
[  115.274537] Call Trace:
[  115.274540]  [] dump_stack+0x4b/0x64
[  115.274543]  [] warn_slowpath_common+0x9f/0xb8
[  115.274545]  [] ? kobject_get+0x33/0x6a
[  115.274547]  [] warn_slowpath_fmt+0x4c/0x4e
[  115.274551]  [] ? lock_is_held+0x55/0x66
[  115.274553]  [] kobject_get+0x33/0x6a
[  115.274554]  [] kobject_add_internal+0x58/0x2c4
[  115.274556]  [] kobject_init_and_add+0x73/0x7e
[  115.274559]  [] ttm_mem_global_init+0xc6/0x2cd
[  115.274563]  [] ? kasan_poison_shadow+0x2f/0x31
[  115.274564]  [] ? kasan_unpoison_shadow+0x14/0x35
[  115.274566]  [] ? kasan_poison_shadow+0x2f/0x31
[  115.274567]  [] ? kasan_kmalloc+0x4b/0x50
[  115.274569]  [] ? __kmalloc+0x13e/0x180
[  115.274571]  [] ? kasan_poison_shadow+0x2f/0x31
[  115.274573]  [] ? drm_global_item_ref+0x67/0xad
[  115.274577]  [] mgag200_ttm_mem_global_init+0x12/0x14
[  115.274579]  [] drm_global_item_ref+0x7e/0xad
[  115.274581]  [] mgag200_mm_init+0x50/0x199
[  115.274583]  [] mgag200_driver_load+0x34a/0x4ba
[  115.274587]  [] drm_dev_register+0x6f/0xb0
[  115.274589]  [] drm_get_pci_dev+0xff/0x1c2
[  115.274590]  [] mga_pci_probe+0xa6/0xad
[  115.274593]  [] local_pci_probe+0x3d/0x82
[  115.274595]  [] 

[patch 3/4] drm/qxl: array underflow in qxl_clientcap_ioctl()

2015-09-17 Thread Frediano Ziglio
> 
> We check that "byte" isn't writing beyond the end of the array but we
> also need to prevent array underflow.
> 
> Signed-off-by: Dan Carpenter 
> 
> diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c
> b/drivers/gpu/drm/qxl/qxl_ioctl.c
> index b2db482..552dc06 100644
> --- a/drivers/gpu/drm/qxl/qxl_ioctl.c
> +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
> @@ -372,7 +372,7 @@ static int qxl_clientcap_ioctl(struct drm_device *dev,
> void *data,
>  {
>   struct qxl_device *qdev = dev->dev_private;
>   struct drm_qxl_clientcap *param = data;
> - int byte, idx;
> + unsigned int byte, idx;
>  
>   byte = param->index / 8;
>   idx = param->index % 8;
> 

Actually there is no underflow. param->index is unsigned so either byte and
idx are at the end positive as long as int is not less then 4 bytes (which
I don't think is supported under Linux).

However I agree with the patch.

Acked!

Frediano Ziglio


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

2015-09-17 Thread Stephen Rothwell
Hi all,

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

  drivers/gpu/drm/i915/i915_irq.c

between commit:

  4e3d1e26c2b2 ("drm/i915: Pass hpd_status_i915[] to intel_get_hpd_pins() in 
pre-g4x")

from Linus' tree and commit:

  58f2cf241fb9 ("drm/i915: Don't call intel_get_hpd_pins() when there's no 
hotplug interrupt")

from the drm-intel tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).

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

diff --cc drivers/gpu/drm/i915/i915_irq.c
index 5a244ab9395b,ca6d806a195a..
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@@ -1557,10 -1652,13 +1652,13 @@@ static void i9xx_hpd_irq_handler(struc
} else {
u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915;

-   intel_get_hpd_pins(_mask, _mask, hotplug_trigger,
-  hotplug_trigger, hpd_status_i915,
-  i9xx_port_hotplug_long_detect);
-   intel_hpd_irq_handler(dev, pin_mask, long_mask);
+   if (hotplug_trigger) {
+   intel_get_hpd_pins(_mask, _mask, 
hotplug_trigger,
 - hotplug_trigger, hpd_status_g4x,
++ hotplug_trigger, hpd_status_i915,
+  i9xx_port_hotplug_long_detect);
+ 
+   intel_hpd_irq_handler(dev, pin_mask, long_mask);
+   }
}
  }



[PATCH 0/3] RFC: Add a drm_aux-dev module.

2015-09-17 Thread Jani Nikula
On Wed, 16 Sep 2015, Ville Syrjälä  wrote:
> On Wed, Sep 16, 2015 at 01:09:54PM -0700, Daniel Vetter wrote:
>> On Tue, Sep 15, 2015 at 10:03:09AM -0700, Rafael Antognolli wrote:
>> > On Tue, Sep 15, 2015 at 07:46:55PM +0300, Ville Syrjälä wrote:
>> > > On Tue, Sep 15, 2015 at 07:41:06PM +0300, Ville Syrjälä wrote:
>> > > > On Tue, Sep 15, 2015 at 09:34:15AM -0700, Rafael Antognolli wrote:
>> > > > > On Tue, Sep 15, 2015 at 10:35:19AM +0300, Ville Syrjälä wrote:
>> > > > > > On Mon, Sep 14, 2015 at 04:12:29PM -0700, Rafael Antognolli wrote:
>> > > > > > > This is a tentative implementation of a module that allows 
>> > > > > > > reading/writing
>> > > > > > > arbitrary dpcd registers, following the suggestion from Daniel 
>> > > > > > > Vetter. It
>> > > > > > > assumes the drm aux helpers were used by the driver.
>> > > > > > > 
>> > > > > > > I tried to follow the i2c-dev implementation as close as 
>> > > > > > > possible, but the only
>> > > > > > > operations that are provided on the dev node are two different 
>> > > > > > > ioctl's, one for
>> > > > > > > reading a register and another one for writing it.
>> > > > > > 
>> > > > > > Why would you use ioctls instead of normal read/write syscalls?
>> > > > > > 
>> > > > > 
>> > > > > For writing, that should work fine, I can easily change that if you
>> > > > > prefer.
>> > > > > 
>> > > > > For reading, one has to first tell which register address is going 
>> > > > > to be
>> > > > > read.
>> > > > 
>> > > > seek()
>> > > 
>> > > Sorry typo. Make that lseek(). 
>> > > 
>> > Oh, nice, I'll update the patch with this and remove the notifier stuff,
>> > thanks!
>> 
>> Well there's also other modes like i2c over aux, and that would be easier
>> to support with an ioctl in a uniform way. So not sure how much value
>> there is in reusing read/write for i2c ...
>
> We already have i2c-dev for i2c. So not sure what you're after here.

Yeah, definitely don't reinvent the wheel for this.

BR,
Jani.

>
> i2c is a bit of a mess on the protocol level. Lots of devices do
> interesting things with it, so it can't really make do with just
> read/write/lseek. Apart from i2c-over-aux, the rest is all about
> DPCD access, and for that read/write/lseek is all you ever need.
>
> -- 
> Ville Syrjälä
> Intel OTC
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Jani Nikula, Intel Open Source Technology Center


[PATCH RFC 6/8] drm: hisilicon: Add support for fbdev

2015-09-17 Thread Rob Clark
On Wed, Sep 16, 2015 at 5:48 AM, Xinliang Liu  
wrote:
>
>
> On 16 September 2015 at 02:25, Rob Herring  wrote:
> Hi Rob, thanks a lot for reply:-)
>
>> On 09/15/2015 04:37 AM, Xinwei Kong wrote:
>> > If you config DRM_HISI_FBDEV optional, this patch will only support
>> > fbdev
>> > mode while also supporting double buffer.
>>
>> This is a lot of duplicated code from CMA fbdev. Is double buffering the
>> only reason why CMA fbdev can't be used or are there some other
>> constraints?
>
> Yes, double buffering is the main reason we rewrite our own fbdev.
> CMA fbdev only create one buffer. But we need at least  double buffer for
> running Android with fbdev.
>
>> Double buffering in fbdev has always been a hack, so I'm
>> guessing that is not a feature that should be added here.
>>
> If so, I think it is hard to be accepted for my cma fbdev patch to support
> multi buffer.
> This early week, I have sent a cma fbdev patch for supporting this. The
> subject is
> "[PATCH] drm/cma-helper: Add multi buffer support for cma fbdev".
> We do have a strong will to support this feature. I described the reason in
> the patch. Please take a look for me. Thank you very much.

fwiw, drm_gralloc has support for kms.  Currently it is expected to be
paired w/ a mesa gpu driver, which might not work for everyone, but I
suppose the display part of it could be extracted out for a
gralloc.kms.so for pure sw rendering.. that might be a better
approach.

http://git.android-x86.org/?p=platform/hardware/drm_gralloc.git

BR,
-R

> -Xinliang
>
>> Rob
>>
>> > Signed-off-by: Xinliang Liu 
>> > Signed-off-by: Xinwei Kong 
>> > Signed-off-by: Andy Green 
>> > Signed-off-by: Jiwen Qi 
>> > Signed-off-by: Yu Gong 
>> > ---
>> >  drivers/gpu/drm/hisilicon/Kconfig  |  13 +
>> >  drivers/gpu/drm/hisilicon/Makefile |   3 +-
>> >  drivers/gpu/drm/hisilicon/hisi_drm_connector.c |   4 +
>> >  drivers/gpu/drm/hisilicon/hisi_drm_drv.c   |   9 +
>> >  drivers/gpu/drm/hisilicon/hisi_drm_dsi.c   |  15 +
>> >  drivers/gpu/drm/hisilicon/hisi_drm_fb.h|   5 +
>> >  drivers/gpu/drm/hisilicon/hisi_drm_fbdev.c | 395
>> > +
>> >  drivers/gpu/drm/hisilicon/hisi_drm_fbdev.h |  24 ++
>> >  8 files changed, 467 insertions(+), 1 deletion(-)
>> >  create mode 100644 drivers/gpu/drm/hisilicon/hisi_drm_fbdev.c
>> >  create mode 100644 drivers/gpu/drm/hisilicon/hisi_drm_fbdev.h
>>
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>


[PATCH 0/3] RFC: Add a drm_aux-dev module.

2015-09-17 Thread Daniel Vetter
On Thu, Sep 17, 2015 at 12:01 AM, Jani Nikula
 wrote:
> On Wed, 16 Sep 2015, Ville Syrjälä  wrote:
>> On Wed, Sep 16, 2015 at 01:09:54PM -0700, Daniel Vetter wrote:
>>> On Tue, Sep 15, 2015 at 10:03:09AM -0700, Rafael Antognolli wrote:
>>> > On Tue, Sep 15, 2015 at 07:46:55PM +0300, Ville Syrjälä wrote:
>>> > > On Tue, Sep 15, 2015 at 07:41:06PM +0300, Ville Syrjälä wrote:
>>> > > > On Tue, Sep 15, 2015 at 09:34:15AM -0700, Rafael Antognolli wrote:
>>> > > > > On Tue, Sep 15, 2015 at 10:35:19AM +0300, Ville Syrjälä wrote:
>>> > > > > > On Mon, Sep 14, 2015 at 04:12:29PM -0700, Rafael Antognolli wrote:
>>> > > > > > > This is a tentative implementation of a module that allows 
>>> > > > > > > reading/writing
>>> > > > > > > arbitrary dpcd registers, following the suggestion from Daniel 
>>> > > > > > > Vetter. It
>>> > > > > > > assumes the drm aux helpers were used by the driver.
>>> > > > > > >
>>> > > > > > > I tried to follow the i2c-dev implementation as close as 
>>> > > > > > > possible, but the only
>>> > > > > > > operations that are provided on the dev node are two different 
>>> > > > > > > ioctl's, one for
>>> > > > > > > reading a register and another one for writing it.
>>> > > > > >
>>> > > > > > Why would you use ioctls instead of normal read/write syscalls?
>>> > > > > >
>>> > > > >
>>> > > > > For writing, that should work fine, I can easily change that if you
>>> > > > > prefer.
>>> > > > >
>>> > > > > For reading, one has to first tell which register address is going 
>>> > > > > to be
>>> > > > > read.
>>> > > >
>>> > > > seek()
>>> > >
>>> > > Sorry typo. Make that lseek().
>>> > >
>>> > Oh, nice, I'll update the patch with this and remove the notifier stuff,
>>> > thanks!
>>>
>>> Well there's also other modes like i2c over aux, and that would be easier
>>> to support with an ioctl in a uniform way. So not sure how much value
>>> there is in reusing read/write for i2c ...
>>
>> We already have i2c-dev for i2c. So not sure what you're after here.
>
> Yeah, definitely don't reinvent the wheel for this.

Of course I didn't mean to reinvent the i2c-dev wheel, but just expose
the underlying low-level dp aux ops to do i2c transaction - that might
be useful for hacking around to figure out some of the recent i2c
changes we've done. Otoh we could add such a raw mode later on as an
ioctl, for plain dpcd reads/writes read/write/lseek seems indeed a
good fit.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH] drm/qxl: only report first monitor as connected if we have no state

2015-09-17 Thread Dave Airlie
From: Dave Airlie 

If the server isn't new enough to give us state, report the first
monitor as always connected, otherwise believe the server side.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/qxl/qxl_display.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 7c6225c..dd845f8 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -886,13 +886,15 @@ static enum drm_connector_status qxl_conn_detect(
drm_connector_to_qxl_output(connector);
struct drm_device *ddev = connector->dev;
struct qxl_device *qdev = ddev->dev_private;
-   int connected;
+   bool connected = false;

/* The first monitor is always connected */
-   connected = (output->index == 0) ||
-   (qdev->client_monitors_config &&
-qdev->client_monitors_config->count > output->index &&
-
qxl_head_enabled(>client_monitors_config->heads[output->index]));
+   if (!qdev->client_monitors_config) {
+   if (output->index == 0)
+   connected = true;
+   } else
+   connected = qdev->client_monitors_config->count > output->index 
&&
+
qxl_head_enabled(>client_monitors_config->heads[output->index]);

DRM_DEBUG("#%d connected: %d\n", output->index, connected);
if (!connected)
-- 
2.4.3



[Bug 102401] Radeon Displayport Audio Warping

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

--- Comment #11 from Maxqia  ---
Any Updates?

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


[PATCH v3 2/2] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support

2015-09-17 Thread Vladimir Zapolskiy
Hi Doug,

On 03.09.2015 02:19, Doug Anderson wrote:
> Russell,
> 
> On Wed, Sep 2, 2015 at 4:04 PM, Russell King - ARM Linux
>  wrote:
 Also, is it appropriate to hook non-DDC devices to a DDC bus?  I suspect
 that's asking for trouble.
>>>
>>> I doubt it's appropriate.  Why do you ask?
>>
>> To find out why you want to "specify the I2C bus".
>>
>> Surely if we're talking about the DDC bus, we either want to use a
>> separate I2C bus (in which case the HDMI DT description needs to
>> specify which I2C bus to use) or we want to use the HDMI-internal
>> I2C bus, which being part of the HDMI driver, the HDMI driver will
>> know how to find it itself - there should be no need to put an
>> explicit ddc-i2c-bus self-reference there in that case.
> 
> Overall it comes down to bus numbering.  Possibly that's a stupid
> reason, but it is my reason nevertheless.

this is a known issue regarding I2C bus numbering.

> Specifically it significantly helps my brain process kernel log
> messages if the i2c bus that's referred to "bus 5" in my SoC's user
> manual shows up consistently as "i2c5" in kernel log messages.  It's
> helpful it it shows up as "i2c5" even if "i2c0" - "i2c4" aren't
> enabled.
> 
> That's all totally possible by using this type of syntax, like in rk3288.dtsi:
> 
> aliases {
>   i2c0 = 
>   i2c1 = 
>   i2c2 = 
>   i2c3 = 
>   i2c4 = 
>   i2c5 = 
> 
> Similarly, I'd like "bus 0" to show up as i2c0, which will happen as
> you can see in the above.
> 
> The problem is that if another bus registers itself before the SoC's
> i2c0 registers itself and that bus doesn't give a number to itself
> then the i2c subsystem will chose "I2C 0".  ...and then when the main
> SoC i2c bus registers itself it will fail because i2c0 is already
> taken.
> 
> By having a of_node for the hdmi i2c bus, we can assign a number to it like:
>   i2c15 = 
> 
> This is all described in the two links I referenced in my original reply.
> 
> 
> A possible other option is to have the i2c subsystem try to start
> numbering at a larger base for all automatically numbered busses
> (those that didn't specify a number).  Then it's more likely (though
> still not guaranteed) to conflict with another bus...

Could you please check if commit 03bde7c31a3 serves you?

--
With best wishes,
Vladimir


[PATCH v3 2/2] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support

2015-09-17 Thread Vladimir Zapolskiy
Hi Doug,

On 16.09.2015 23:04, Doug Anderson wrote:
> Hi,
> 
> On Sun, Aug 30, 2015 at 2:34 PM, Vladimir Zapolskiy
>  wrote:
>> The change adds support of internal HDMI I2C master controller, this
>> subdevice is used by default, if "ddc-i2c-bus" DT property is omitted.
>>
>> The main purpose of this functionality is to support reading EDID from
>> an HDMI monitor on boards, which don't have an I2C bus connected to
>> DDC pins.
>>
>> The current implementation does not support "I2C Master Interface
>> Extended Read Mode" to read data addressed by non-zero segment
>> pointer, this means that if EDID has more than 1 extension blocks,
>> EDID reading operation won't succeed, in my practice all tested HDMI
>> monitors have at maximum one extension block.
>>
>> Signed-off-by: Vladimir Zapolskiy 
>> ---
>> The change is based on today's v4.2, please let me know, if it should be 
>> rebased.
>>
>> The change has compilation dependency on I2CM_ADDRESS register name fix,
>> see http://lists.freedesktop.org/archives/dri-devel/2015-May/082980.html
>>
>> From http://lists.freedesktop.org/archives/dri-devel/2015-May/082981.html
>> v1 of the change was
>>
>>   Tested-by: Philipp Zabel 
>>
>> but I hesitate to add the tag here due to multiple updates in v2.
>>
>> Changes from v2 to v3, thanks to Russell:
>> - moved register field value definitions to dw_hdmi.h
>> - made completions uninterruptible to avoid transfer retries if interrupted
>> - use one completion for both read and write transfers as in v1, 
>> operation_reg is removed
>> - redundant i2c->stat = 0 is removed from dw_hdmi_i2c_read/write()
>> - struct i2c_algorithm dw_hdmi_algorithm is qualified as const
>> - dw_hdmi_i2c_adapter() does not modify struct dw_hdmi on error path
>> - dw_hdmi_i2c_irq() does not modify hdmi->i2c->stat, if interrupt is not for 
>> I2CM
>> - spin lock is removed from dw_hdmi_i2c_irq()
>> - removed spin lock from dw_hdmi_i2c_xfer() around write to 
>> HDMI_IH_MUTE_I2CM_STAT0 register
>> - split loop over message array in dw_hdmi_i2c_xfer() to validation and 
>> transfer parts
>> - added a mutex to serialize I2C transfer requests, i2c->lock is completely 
>> removed
>> - removed if(len) check from dw_hdmi_i2c_write(), hardware supports only 
>> len>0 transfers
>> - described extension blocks <= 1 limitation in the commit message
>> - a number of minor clean ups
>>
>> Changes from v1 to v2:
>> - fixed a devm_kfree() signature
>> - split completions for read and write operations
>>
>>  drivers/gpu/drm/bridge/dw_hdmi.c | 262 
>> ++-
>>  drivers/gpu/drm/bridge/dw_hdmi.h |  19 +++
>>  2 files changed, 275 insertions(+), 6 deletions(-)
> 
> Not sure what the status of this patch is, but I'll make a few more
> suggestions in case they're helpful.

sure, all review comments are welcome.

I have in mind that Philipp asked to add an update to documentation, the
next version will contain the fixes.

> 
>> +static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
>> +{
>> +   /* Set Fast Mode speed */
>> +   hdmi_writeb(hdmi, 0x0b, HDMI_I2CM_DIV);
> 
> If you're going to hardcode to something, it seems like hardcoding to
> standard mode might be better?  It's likely that users will plug into
> all kinds of broken / crappy HDMI devices out there.  I think you'll
> get better compatibility by using the slower mode, and EDID transfers
> really aren't too performance critical are they?
> 

Accepted. I don't know what are the exact divisors of master clock for
fast and standard modes, for reference I'll make a simple performance
test and publish its results. I expect that in standard mode SCL is
about 100KHz and in fast mode SCL is about 400KHz, and, if in standard
mode SCL is less than 100KHz, it will take more than 50ms to read out
512 bytes of data, which might be not acceptable from performance
perspective.

>> +
>> +   /* Software reset */
>> +   hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ);
> 
> Unless there's a reason not to, it seems like the reset ought to be
> the first thing in this function (before setting the I2CM_DIV).  Even
> if it doesn't actually reset the speed on current hardware, it just
> seems cleaner.

It makes sense for me.

> 
>> +static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
>> +   struct i2c_msg *msgs, int num)
>> +{
>> +   struct dw_hdmi *hdmi = i2c_get_adapdata(adap);
>> +   struct dw_hdmi_i2c *i2c = hdmi->i2c;
>> +   u8 addr = msgs[0].addr;
>> +   int i, ret = 0;
>> +
>> +   dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr);
>> +
>> +   for (i = 0; i < num; i++) {
>> +   if (msgs[i].addr != addr) {
>> +   dev_warn(hdmi->dev,
>> +"unsupported transfer, changed slave 
>> address\n");
>> +   return -EOPNOTSUPP;
>> +   }
>> +
>> +   if (msgs[i].len == 0) {
>> +   dev_dbg(hdmi->dev,
>> +  

[PATCH 0/3] RFC: Add a drm_aux-dev module.

2015-09-17 Thread Ville Syrjälä
On Wed, Sep 16, 2015 at 01:09:54PM -0700, Daniel Vetter wrote:
> On Tue, Sep 15, 2015 at 10:03:09AM -0700, Rafael Antognolli wrote:
> > On Tue, Sep 15, 2015 at 07:46:55PM +0300, Ville Syrjälä wrote:
> > > On Tue, Sep 15, 2015 at 07:41:06PM +0300, Ville Syrjälä wrote:
> > > > On Tue, Sep 15, 2015 at 09:34:15AM -0700, Rafael Antognolli wrote:
> > > > > On Tue, Sep 15, 2015 at 10:35:19AM +0300, Ville Syrjälä wrote:
> > > > > > On Mon, Sep 14, 2015 at 04:12:29PM -0700, Rafael Antognolli wrote:
> > > > > > > This is a tentative implementation of a module that allows 
> > > > > > > reading/writing
> > > > > > > arbitrary dpcd registers, following the suggestion from Daniel 
> > > > > > > Vetter. It
> > > > > > > assumes the drm aux helpers were used by the driver.
> > > > > > > 
> > > > > > > I tried to follow the i2c-dev implementation as close as 
> > > > > > > possible, but the only
> > > > > > > operations that are provided on the dev node are two different 
> > > > > > > ioctl's, one for
> > > > > > > reading a register and another one for writing it.
> > > > > > 
> > > > > > Why would you use ioctls instead of normal read/write syscalls?
> > > > > > 
> > > > > 
> > > > > For writing, that should work fine, I can easily change that if you
> > > > > prefer.
> > > > > 
> > > > > For reading, one has to first tell which register address is going to 
> > > > > be
> > > > > read.
> > > > 
> > > > seek()
> > > 
> > > Sorry typo. Make that lseek(). 
> > > 
> > Oh, nice, I'll update the patch with this and remove the notifier stuff,
> > thanks!
> 
> Well there's also other modes like i2c over aux, and that would be easier
> to support with an ioctl in a uniform way. So not sure how much value
> there is in reusing read/write for i2c ...

We already have i2c-dev for i2c. So not sure what you're after here.

i2c is a bit of a mess on the protocol level. Lots of devices do
interesting things with it, so it can't really make do with just
read/write/lseek. Apart from i2c-over-aux, the rest is all about
DPCD access, and for that read/write/lseek is all you ever need.

-- 
Ville Syrjälä
Intel OTC


[PATCH 2/3] drm: fix kernel-doc warnings in drm_crtc.h

2015-09-17 Thread Geliang Tang
Fix the following 'make htmldocs' warning:

  .//include/drm/drm_crtc.h:929: warning: Excess struct/union/enum/typedef 
member 'base' description in 'drm_bridge'

Signed-off-by: Geliang Tang 
---
 include/drm/drm_crtc.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c0366e9..6566f72 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -911,7 +911,6 @@ struct drm_bridge_funcs {
  * @next: the next bridge in the encoder chain
  * @of_node: device node pointer to the bridge
  * @list: to keep track of all added bridges
- * @base: base mode object
  * @funcs: control functions
  * @driver_private: pointer to the bridge driver's internal context
  */
-- 
1.9.1




[PATCH v3 2/2] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support

2015-09-17 Thread Russell King - ARM Linux
On Wed, Sep 16, 2015 at 02:56:57PM -0700, Doug Anderson wrote:
> Yes, I'd expect 100kHz and 400kHz.
> 
> I agree that 50ms is non-trivial, but it's also not something you're
> doing lots of.  I'd expect that the EDID is read over this channel at
> cable plugin time and then not used much after that.  Adding an extra
> 40ms (10ms vs 50ms) before we can access the TV doesn't seem terrible
> for compatibility.
> 
> Doing a quick scan for what others in mainline do:
> 
> A few can be found with:
> 
> $ git grep -A3 hdmiddc | grep clock-freq
> arch/arm/boot/dts/stihxxx-b2120.dtsi-
> clock-frequency = <10>;
> arch/arm/boot/dts/tegra30-apalis.dtsi-  clock-frequency = <10>;
> arch/arm/boot/dts/tegra30-beaver.dts-   clock-frequency = <10>;
> arch/arm/boot/dts/tegra30-colibri.dtsi- clock-frequency = <10>;

This is a sure way to propagate a bug.

I said in a previous email that you need to check the HDMI and CEA
specs.  I've done this, and HDMI 1.3a specifies a maximum SCL clock
rate of 100kHz.

So that's settled then.  100kHz is must be.  Using 400kHz is out of
specification.

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


[PATCH 23/23] drm/i915: BDW: Pipe level degamma correction

2015-09-17 Thread Shashank Sharma
BDW/SKL/BXT supports Degamma color correction feature, which
linearizes the non-linearity due to gamma encoded color values.
This will be applied before Color Transformation.

This patch does the following:
1. Adds the core function to program DeGamma correction values for
   BDW/SKL/BXT platform
2. Adds DeGamma correction macros/defines

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/intel_color_manager.c | 61 ++
 1 file changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index d935fd8..46f880d 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -532,6 +532,65 @@ static int bdw_set_gamma(struct drm_device *dev, struct 
drm_property_blob *blob,
return 0;
 }

+static int bdw_set_degamma(struct drm_device *dev,
+   struct drm_property_blob *blob, struct drm_crtc *crtc)
+{
+   enum pipe pipe;
+   int num_samples, length;
+   int count = 0;
+   u32 index, word;
+   u32 blue, green, red;
+   u32 mode, pal_prec_index, pal_prec_data;
+   struct drm_palette *degamma_data;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_r32g32b32 *correction_values = NULL;
+
+   if (WARN_ON(!blob))
+   return -EINVAL;
+
+   degamma_data = (struct drm_palette *)blob->data;
+   if (degamma_data->version != DEGAMMA_DATA_STRUCT_VERSION) {
+   DRM_ERROR("Invalid DeGamma Data struct version\n");
+   return -EINVAL;
+   }
+
+   pipe = to_intel_crtc(crtc)->pipe;
+   num_samples = degamma_data->num_samples;
+   if (num_samples != BDW_SPLITGAMMA_MAX_VALS) {
+   DRM_ERROR("Invalid number of samples\n");
+   return -EINVAL;
+   }
+
+   length = num_samples * sizeof(struct drm_r32g32b32);
+   mode = I915_READ(GAMMA_MODE(pipe));
+   pal_prec_index = _PREC_PAL_INDEX(pipe);
+   pal_prec_data = _PREC_PAL_DATA(pipe);
+
+   correction_values = (struct drm_r32g32b32 *)_data->lut;
+   index = I915_READ(pal_prec_index);
+   index |= BDW_INDEX_AUTO_INCREMENT | BDW_INDEX_SPLIT_MODE;
+   I915_WRITE(pal_prec_index, index);
+
+   while (count < num_samples) {
+   blue = correction_values[count].b32;
+   green = correction_values[count].g32;
+   red = correction_values[count].r32;
+
+   word = bdw_write_10bit_gamma_precision(red, green, blue);
+   I915_WRITE(pal_prec_data, word);
+   count++;
+   }
+
+   /* Enable DeGamma on Pipe */
+   mode &= ~GAMMA_MODE_MODE_MASK;
+   I915_WRITE(GAMMA_MODE(pipe), mode | GAMMA_MODE_MODE_SPLIT);
+
+   DRM_DEBUG_DRIVER("DeGamma correction enabled on Pipe %c\n",
+   pipe_name(pipe));
+
+   return 0;
+}
+
 static int chv_set_gamma(struct drm_device *dev, struct drm_property_blob 
*blob,
  struct drm_crtc *crtc)
 {
@@ -700,6 +759,8 @@ void intel_color_manager_crtc_commit(struct drm_device *dev,
/* degamma correction */
if (IS_CHERRYVIEW(dev))
ret = chv_set_degamma(dev, blob, crtc);
+   else if (IS_BROADWELL(dev) || IS_GEN9(dev))
+   ret = bdw_set_degamma(dev, blob, crtc);

if (ret)
DRM_ERROR("set degamma correction failed\n");
-- 
1.9.1



[PATCH 22/23] drm/i915: BDW: Load degamma correction values

2015-09-17 Thread Shashank Sharma
I915 color manager registers pipe degamma correction as palette
correction before CTM, DRM property.

This patch adds the no of coefficients(65) for degamma correction
as "num_samples_before_ctm" parameter in device info structures,
for BDW and higher platforms.

Signed-off-by: Shashank Sharma 
---
 drivers/gpu/drm/i915/i915_drv.c| 7 +++
 drivers/gpu/drm/i915/intel_color_manager.h | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 69afed3..23ad2cc 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -303,6 +303,7 @@ static const struct intel_device_info 
intel_broadwell_d_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
+   .num_samples_before_ctm = BDW_DEGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -316,6 +317,7 @@ static const struct intel_device_info 
intel_broadwell_m_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
+   .num_samples_before_ctm = BDW_DEGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -329,6 +331,7 @@ static const struct intel_device_info 
intel_broadwell_gt3d_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
.num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
+   .num_samples_before_ctm = BDW_DEGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -342,6 +345,7 @@ static const struct intel_device_info 
intel_broadwell_gt3m_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
.num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
+   .num_samples_before_ctm = BDW_DEGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -368,6 +372,7 @@ static const struct intel_device_info intel_skylake_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
+   .num_samples_before_ctm = BDW_DEGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -382,6 +387,7 @@ static const struct intel_device_info 
intel_skylake_gt3_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
.num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
+   .num_samples_before_ctm = BDW_DEGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -396,6 +402,7 @@ static const struct intel_device_info intel_broxton_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
+   .num_samples_before_ctm = BDW_DEGAMMA_MAX_VALS,
.num_pipes = 3,
.has_ddi = 1,
.has_fpga_dbg = 1,
diff --git a/drivers/gpu/drm/i915/intel_color_manager.h 
b/drivers/gpu/drm/i915/intel_color_manager.h
index 17fcf3d..a428825 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.h
+++ b/drivers/gpu/drm/i915/intel_color_manager.h
@@ -72,6 +72,8 @@
 #define CHV_DEGAMMA_MSB_SHIFT  2
 #define CHV_DEGAMMA_GREEN_SHIFT16

+#define BDW_DEGAMMA_MAX_VALS   512
+
 /* CSC correction */
 #define CSC_DATA_STRUCT_VERSION1
 /*
-- 
1.9.1



[PATCH 21/23] drm/i915: BDW: Pipe level Gamma correction

2015-09-17 Thread Shashank Sharma
BDW/SKL/BXT platforms support various Gamma correction modes
which are:
1. Legacy 8-bit mode
2. 10-bit mode
3. 10-bit Split Gamma mode
4. 12-bit mode

This patch does the following:
1. Adds the core function to program Gamma correction values
   for BDW/SKL/BXT platforms
2. Adds Gamma correction macros/defines

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/i915_reg.h|  17 +-
 drivers/gpu/drm/i915/intel_color_manager.c | 270 +
 drivers/gpu/drm/i915/intel_color_manager.h |  15 ++
 3 files changed, 300 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5c7759d..88f4e41 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5634,7 +5634,9 @@ enum skl_disp_power_wells {

 #define _GAMMA_MODE_A  0x4a480
 #define _GAMMA_MODE_B  0x4ac80
-#define GAMMA_MODE(pipe) _PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B)
+#define _GAMMA_MODE_C  0x4b480
+#define GAMMA_MODE(pipe) \
+   _PIPE3(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B, _GAMMA_MODE_C)
 #define GAMMA_MODE_MODE_MASK   (3 << 0)
 #define GAMMA_MODE_MODE_8BIT   (0 << 0)
 #define GAMMA_MODE_MODE_10BIT  (1 << 0)
@@ -8001,6 +8003,17 @@ enum skl_disp_power_wells {
 #define _PIPE_CSC_BASE(pipe) \
(_PIPE3(pipe, PIPEA_CGM_CSC, PIPEB_CGM_CSC, PIPEC_CGM_CSC))

-
+/* BDW gamma correction */
+#define PAL_PREC_INDEX_A   0x4A400
+#define PAL_PREC_INDEX_B   0x4AC00
+#define PAL_PREC_INDEX_C   0x4B400
+#define PAL_PREC_DATA_A0x4A404
+#define PAL_PREC_DATA_B0x4AC04
+#define PAL_PREC_DATA_C0x4B404
+
+#define _PREC_PAL_INDEX(pipe) \
+   (_PIPE3(pipe, PAL_PREC_INDEX_A, PAL_PREC_INDEX_B, PAL_PREC_INDEX_C))
+#define _PREC_PAL_DATA(pipe) \
+   (_PIPE3(pipe, PAL_PREC_DATA_A, PAL_PREC_DATA_B, PAL_PREC_DATA_C))

 #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index d33a2be..d935fd8 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -264,6 +264,274 @@ static int chv_set_degamma(struct drm_device *dev,
return ret;
 }

+static u32 bdw_write_10bit_gamma_precision(u32 red, u32 green, u32 blue)
+{
+   u32 word;
+   u8 blue_int, green_int, red_int;
+   u16 blue_fract, green_fract, red_fract;
+
+   blue_int = _GAMMA_INT_PART(blue);
+   if (blue_int > GAMMA_INT_MAX)
+   blue = BDW_MAX_GAMMA;
+
+   green_int = _GAMMA_INT_PART(green);
+   if (green_int > GAMMA_INT_MAX)
+   green = BDW_MAX_GAMMA;
+
+   red_int = _GAMMA_INT_PART(red);
+   if (red_int > GAMMA_INT_MAX)
+   red = BDW_MAX_GAMMA;
+
+   blue_fract = _GAMMA_FRACT_PART(blue);
+   green_fract = _GAMMA_FRACT_PART(green);
+   red_fract = _GAMMA_FRACT_PART(red);
+
+   blue_fract >>= BDW_10BIT_GAMMA_MSB_SHIFT;
+   green_fract >>= BDW_10BIT_GAMMA_MSB_SHIFT;
+   red_fract >>= BDW_10BIT_GAMMA_MSB_SHIFT;
+
+   /* Red (29:20) Green (19:10) and Blue (9:0) */
+   word = red_fract;
+   word <<= BDW_GAMMA_SHIFT;
+   word = word | green_fract;
+   word <<= BDW_GAMMA_SHIFT;
+   word = word | blue_fract;
+
+   return word;
+}
+
+/* Apply unity gamma for gamma reset */
+static void bdw_reset_gamma(struct drm_i915_private *dev_priv,
+   enum pipe pipe)
+{
+   u16 count = 0;
+   u32 val;
+   u32 pal_prec_data = LGC_PALETTE(pipe);
+
+   DRM_DEBUG_DRIVER("\n");
+
+   /* Reset the palette for unit gamma */
+   while (count < BDW_8BIT_GAMMA_MAX_VALS) {
+   /* Red (23:16) Green (15:8) and Blue (7:0) */
+   val = (count << 16) | (count << 8) | count;
+   I915_WRITE(pal_prec_data, val);
+   pal_prec_data += 4;
+   count++;
+   }
+}
+
+static int bdw_set_gamma(struct drm_device *dev, struct drm_property_blob 
*blob,
+  struct drm_crtc *crtc)
+{
+   u8 blue_int, green_int, red_int;
+   u16 blue_fract, green_fract, red_fract;
+   u16 blue_odd, green_odd, red_odd;
+   u16 blue_even, green_even, red_even;
+
+   enum pipe pipe;
+   int count, num_samples;
+   u32 blue, green, red;
+   u32 mode, pal_prec_index, pal_prec_data;
+   u32 index, word;
+   struct drm_palette *gamma_data;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_r32g32b32 *correction_values = NULL;
+
+   if (!blob) {
+   DRM_ERROR("Null Blob\n");
+   return -EINVAL;
+   }
+
+   gamma_data = (struct drm_palette *)blob->data;
+
+   if (gamma_data->version != GAMMA_DATA_STRUCT_VERSION) {
+   DRM_DEBUG_KMS("Invalid Gamma Data struct version\n");
+ 

[PATCH 20/23] drm/i915: BDW: Load gamma correction values

2015-09-17 Thread Shashank Sharma
I915 color manager registers pipe gamma correction as palette
correction after CTM property.

For BDW and higher platforms, split gamma correction is the best
gamma correction. This patch adds the no of coefficients(512) for
split gamma correction as "num_samples_after_ctm" parameter in device
info structures, for all of those.

Signed-off-by: Shashank Sharma 
---
 drivers/gpu/drm/i915/i915_drv.c| 7 +++
 drivers/gpu/drm/i915/intel_color_manager.h | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 03db841..69afed3 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -302,6 +302,7 @@ static const struct intel_device_info 
intel_broadwell_d_info = {
.gen = 8, .num_pipes = 3,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+   .num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -314,6 +315,7 @@ static const struct intel_device_info 
intel_broadwell_m_info = {
.gen = 8, .is_mobile = 1, .num_pipes = 3,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+   .num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -326,6 +328,7 @@ static const struct intel_device_info 
intel_broadwell_gt3d_info = {
.gen = 8, .num_pipes = 3,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
+   .num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -338,6 +341,7 @@ static const struct intel_device_info 
intel_broadwell_gt3m_info = {
.gen = 8, .is_mobile = 1, .num_pipes = 3,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
+   .num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -363,6 +367,7 @@ static const struct intel_device_info intel_skylake_info = {
.gen = 9, .num_pipes = 3,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+   .num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -376,6 +381,7 @@ static const struct intel_device_info 
intel_skylake_gt3_info = {
.gen = 9, .num_pipes = 3,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
+   .num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
@@ -389,6 +395,7 @@ static const struct intel_device_info intel_broxton_info = {
.gen = 9,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+   .num_samples_after_ctm = BDW_SPLITGAMMA_MAX_VALS,
.num_pipes = 3,
.has_ddi = 1,
.has_fpga_dbg = 1,
diff --git a/drivers/gpu/drm/i915/intel_color_manager.h 
b/drivers/gpu/drm/i915/intel_color_manager.h
index 6e5158e..3687989 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.h
+++ b/drivers/gpu/drm/i915/intel_color_manager.h
@@ -42,6 +42,8 @@
 #define CHV_10BIT_GAMMA_MSB_SHIFT  6
 #define CHV_GAMMA_SHIFT_GREEN  16

+#define BDW_SPLITGAMMA_MAX_VALS512
+
 /* Gamma values are u8.24 format */
 #define GAMMA_INT_SHIFT24
 #define GAMMA_FRACT_SHIFT  8
-- 
1.9.1



[PATCH 19/23] drm/i915: Attach color properties to CRTC

2015-09-17 Thread Shashank Sharma
Function intel_attach_color_properties_to_crtc attaches a
color property to its CRTC object. This patch calls this
function from crtc initialization sequence.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/intel_display.c | 1 +
 drivers/gpu/drm/i915/intel_drv.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 9b9d267..8b5f266 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13818,6 +13818,7 @@ static void intel_crtc_init(struct drm_device *dev, int 
pipe)
intel_crtc->cursor_size = ~0;

intel_crtc->wm.cxsr_allowed = true;
+   intel_attach_color_properties_to_crtc(dev, _crtc->base.base);

BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
   dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f87a99d..f992345 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1478,4 +1478,6 @@ int intel_color_manager_set_pipe_csc(struct drm_device 
*dev,
struct drm_mode_object *obj, uint32_t blob_id);
 void intel_color_manager_crtc_commit(struct drm_device *dev,
struct drm_crtc_state *crtc_state);
+void intel_attach_color_properties_to_crtc(struct drm_device *dev,
+   struct drm_mode_object *mode_obj);
 #endif /* __INTEL_DRV_H__ */
-- 
1.9.1



[PATCH 18/23] drm/i915: Commit color changes to CRTC

2015-09-17 Thread Shashank Sharma
The color correction blob values are loaded during set_property
calls. This patch adds a function to find the blob and apply the
correction values to the display registers, during the atomic
commit call.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/intel_color_manager.c | 46 ++
 drivers/gpu/drm/i915/intel_display.c   |  2 ++
 drivers/gpu/drm/i915/intel_drv.h   |  2 ++
 3 files changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index 22b708f..d33a2be 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -406,6 +406,52 @@ int intel_color_manager_set_pipe_gamma(struct drm_device 
*dev,
return 0;
 }

+void intel_color_manager_crtc_commit(struct drm_device *dev,
+   struct drm_crtc_state *crtc_state)
+{
+   struct drm_property_blob *blob;
+   struct drm_crtc *crtc = crtc_state->crtc;
+   int ret = -EINVAL;
+
+   blob = crtc_state->palette_after_ctm_blob;
+   if (blob) {
+   /* Gamma correction is platform specific */
+   if (IS_CHERRYVIEW(dev))
+   ret = chv_set_gamma(dev, blob, crtc);
+
+   if (ret)
+   DRM_ERROR("set Gamma correction failed\n");
+   else
+   DRM_DEBUG_DRIVER("Gamma correction success\n");
+   }
+
+   blob = crtc_state->palette_before_ctm_blob;
+   if (blob) {
+   /* degamma correction */
+   if (IS_CHERRYVIEW(dev))
+   ret = chv_set_degamma(dev, blob, crtc);
+
+   if (ret)
+   DRM_ERROR("set degamma correction failed\n");
+   else
+   DRM_DEBUG_DRIVER("degamma correction success\n");
+   }
+
+   blob = crtc_state->ctm_blob;
+   if (blob) {
+   /* CSC correction */
+   if (IS_CHERRYVIEW(dev))
+   ret = chv_set_csc(dev, blob, crtc);
+
+   if (ret)
+   DRM_ERROR("set CSC correction failed\n");
+   else
+   DRM_DEBUG_DRIVER("CSC correction success\n");
+   }
+
+}
+
+
 int get_pipe_capabilities(struct drm_device *dev,
struct drm_palette_caps *palette_caps, struct drm_crtc *crtc)
 {
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 010acca..9b9d267 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13487,6 +13487,8 @@ static void intel_begin_crtc_commit(struct drm_crtc 
*crtc,
intel_update_pipe_config(intel_crtc, old_intel_state);
else if (INTEL_INFO(dev)->gen >= 9)
skl_detach_scalers(intel_crtc);
+
+   intel_color_manager_crtc_commit(dev, crtc->state);
 }

 static void intel_finish_crtc_commit(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4d571a2f..f87a99d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1476,4 +1476,6 @@ int intel_color_manager_set_pipe_degamma(struct 
drm_device *dev,
 int intel_color_manager_set_pipe_csc(struct drm_device *dev,
struct drm_crtc_state *crtc_state,
struct drm_mode_object *obj, uint32_t blob_id);
+void intel_color_manager_crtc_commit(struct drm_device *dev,
+   struct drm_crtc_state *crtc_state);
 #endif /* __INTEL_DRV_H__ */
-- 
1.9.1



[PATCH 17/23] drm/i915: CHV: Pipe level CSC correction

2015-09-17 Thread Shashank Sharma
CHV/BSW supports Color Space Conversion (CSC) using a 3x3 matrix
that needs to be programmed into CGM (Color Gamut Mapping) registers.

This patch does the following:
1. Attaches CSC property to CRTC
2. Adds the core function to program CSC correction values
3. Adds CSC correction macros

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/i915_reg.h|  8 +++
 drivers/gpu/drm/i915/intel_color_manager.c | 99 ++
 drivers/gpu/drm/i915/intel_color_manager.h | 20 ++
 3 files changed, 127 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3dde6a8..5c7759d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7995,4 +7995,12 @@ enum skl_disp_power_wells {
 #define _PIPE_DEGAMMA_BASE(pipe) \
(_PIPE3(pipe, PIPEA_CGM_DEGAMMA, PIPEB_CGM_DEGAMMA, PIPEC_CGM_DEGAMMA))

+#define PIPEA_CGM_CSC  (VLV_DISPLAY_BASE + 0x67900)
+#define PIPEB_CGM_CSC  (VLV_DISPLAY_BASE + 0x69900)
+#define PIPEC_CGM_CSC  (VLV_DISPLAY_BASE + 0x6B900)
+#define _PIPE_CSC_BASE(pipe) \
+   (_PIPE3(pipe, PIPEA_CGM_CSC, PIPEB_CGM_CSC, PIPEC_CGM_CSC))
+
+
+
 #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index e2ffbdc..22b708f 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -66,6 +66,99 @@ int intel_color_manager_set_pipe_degamma(struct drm_device 
*dev,
return 0;
 }

+static s16 get_csc_s3_12_format(s64 csc_value)
+{
+   s32 csc_int_value;
+   u32 csc_fract_value;
+   s16 csc_s3_12_format;
+
+   if (csc_value >= 0) {
+   csc_value += CHV_CSC_FRACT_ROUNDOFF;
+   if (csc_value > CHV_CSC_COEFF_MAX)
+   csc_value = CHV_CSC_COEFF_MAX;
+   } else {
+   csc_value = -csc_value;
+   csc_value += CHV_CSC_FRACT_ROUNDOFF;
+   if (csc_value > CHV_CSC_COEFF_MAX + 1)
+   csc_value = CHV_CSC_COEFF_MAX + 1;
+   csc_value = -csc_value;
+   }
+
+   csc_int_value = csc_value >> CHV_CSC_COEFF_SHIFT;
+   csc_int_value <<= CHV_CSC_COEFF_INT_SHIFT;
+   if (csc_value < 0)
+   csc_int_value |= CSC_COEFF_SIGN;
+   csc_fract_value = csc_value;
+   csc_fract_value >>= CHV_CSC_COEFF_FRACT_SHIFT;
+   csc_s3_12_format = csc_int_value | csc_fract_value;
+
+   return csc_s3_12_format;
+}
+
+static int chv_set_csc(struct drm_device *dev, struct drm_property_blob *blob,
+   struct drm_crtc *crtc)
+{
+   struct drm_ctm *csc_data;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   u32 reg;
+   enum pipe pipe;
+   s32 word, temp;
+   int count = 0;
+
+   if (!blob) {
+   DRM_ERROR("NULL Blob\n");
+   return -EINVAL;
+   }
+
+   if (blob->length != sizeof(struct drm_ctm)) {
+   DRM_ERROR("Invalid length of data received\n");
+   return -EINVAL;
+   }
+
+   csc_data = (struct drm_ctm *)blob->data;
+   if (csc_data->version != CSC_DATA_STRUCT_VERSION) {
+   DRM_ERROR("Invalid CSC Data struct version\n");
+   return -EINVAL;
+   }
+
+   pipe = to_intel_crtc(crtc)->pipe;
+
+   /* Disable CSC functionality */
+   reg = _PIPE_CGM_CONTROL(pipe);
+   I915_WRITE(reg, I915_READ(reg) & (~CGM_CSC_EN));
+
+   DRM_DEBUG_DRIVER("Disabled CSC Functionality on Pipe %c\n",
+   pipe_name(pipe));
+
+   reg = _PIPE_CSC_BASE(pipe);
+   while (count < CSC_MAX_VALS) {
+   word = get_csc_s3_12_format(csc_data->ctm_coeff[count]);
+
+   /*
+* Last value to be written in 1 register.
+* Otherwise, each pair of CSC values go
+* into 1 register
+*/
+   if (count != (CSC_MAX_VALS - 1)) {
+   count++;
+   temp = get_csc_s3_12_format(csc_data->ctm_coeff[count]);
+   word |= temp;
+   }
+   I915_WRITE(reg, word);
+   reg += 4;
+   count++;
+   }
+
+   DRM_DEBUG_DRIVER("All CSC values written to registers\n");
+
+   /* Enable CSC functionality */
+   reg = _PIPE_CGM_CONTROL(pipe);
+   I915_WRITE(reg, I915_READ(reg) | CGM_CSC_EN);
+   DRM_DEBUG_DRIVER("CSC enabled on Pipe %c\n", pipe_name(pipe));
+
+   return 0;
+}
+
 static int chv_set_degamma(struct drm_device *dev,
struct drm_property_blob *blob, struct drm_crtc *crtc)
 {
@@ -372,5 +465,11 @@ void intel_attach_color_properties_to_crtc(struct 
drm_device *dev,
DRM_DEBUG_DRIVER("palette before CTM attached to CRTC\n");
}

+   if (config->cm_ctm_property) {

[PATCH 16/23] drm/i915: CHV: Pipe level degamma correction

2015-09-17 Thread Shashank Sharma
CHV/BSW supports DeGamma color correction, which linearizes all
the non-linear color values. This will be applied before Color
Transformation.

This patch does the following:
1. Attach deGamma property to CRTC
2. Add the core function to program DeGamma correction values for
   CHV/BSW platform
2. Add DeGamma correction macros/defines

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/i915_reg.h|   6 ++
 drivers/gpu/drm/i915/intel_color_manager.c | 111 +
 drivers/gpu/drm/i915/intel_color_manager.h |   6 ++
 3 files changed, 123 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 93aa1f9..3dde6a8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7989,4 +7989,10 @@ enum skl_disp_power_wells {
 #define _PIPE_GAMMA_BASE(pipe) \
(_PIPE3(pipe, PIPEA_CGM_GAMMA, PIPEB_CGM_GAMMA, PIPEC_CGM_GAMMA))

+#define PIPEA_CGM_DEGAMMA  (VLV_DISPLAY_BASE + 0x66000)
+#define PIPEB_CGM_DEGAMMA  (VLV_DISPLAY_BASE + 0x68000)
+#define PIPEC_CGM_DEGAMMA  (VLV_DISPLAY_BASE + 0x6A000)
+#define _PIPE_DEGAMMA_BASE(pipe) \
+   (_PIPE3(pipe, PIPEA_CGM_DEGAMMA, PIPEB_CGM_DEGAMMA, PIPEC_CGM_DEGAMMA))
+
 #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index 222924d..e2ffbdc 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -66,6 +66,111 @@ int intel_color_manager_set_pipe_degamma(struct drm_device 
*dev,
return 0;
 }

+static int chv_set_degamma(struct drm_device *dev,
+   struct drm_property_blob *blob, struct drm_crtc *crtc)
+{
+   struct drm_palette *degamma_data;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   u32 cgm_control_reg = 0;
+   u32 cgm_degamma_reg = 0;
+   enum pipe pipe;
+   u32 red, green, blue;
+   u8 red_int, green_int, blue_int;
+   u16 red_fract, green_fract, blue_fract;
+   u32 count = 0;
+   struct drm_r32g32b32 *correction_values = NULL;
+   u32 num_samples;
+   u32 word;
+   int ret = 0, length;
+
+   if (!blob) {
+   DRM_ERROR("NULL Blob\n");
+   return -EINVAL;
+   }
+
+   degamma_data = (struct drm_palette *)blob->data;
+
+   if (degamma_data->version != DEGAMMA_DATA_STRUCT_VERSION) {
+   DRM_ERROR("Invalid DeGamma Data struct version\n");
+   return -EINVAL;
+   }
+
+   pipe = to_intel_crtc(crtc)->pipe;
+   num_samples = degamma_data->num_samples;
+   length = num_samples * sizeof(struct drm_r32g32b32);
+
+   if (num_samples == 0) {
+
+   /* Disable DeGamma functionality on Pipe - CGM Block */
+   cgm_control_reg = I915_READ(_PIPE_CGM_CONTROL(pipe));
+   cgm_control_reg &= ~CGM_DEGAMMA_EN;
+   I915_WRITE(_PIPE_CGM_CONTROL(pipe), cgm_control_reg);
+
+   DRM_DEBUG_DRIVER("DeGamma disabled on Pipe %c\n",
+   pipe_name(pipe));
+   ret = 0;
+   } else if (num_samples == CHV_DEGAMMA_MAX_VALS) {
+   cgm_degamma_reg = _PIPE_DEGAMMA_BASE(pipe);
+
+   count = 0;
+   correction_values = (struct drm_r32g32b32 *)_data->lut;
+   while (count < CHV_DEGAMMA_MAX_VALS) {
+   blue = correction_values[count].b32;
+   green = correction_values[count].g32;
+   red = correction_values[count].r32;
+
+   blue_int = _GAMMA_INT_PART(blue);
+   if (blue_int > GAMMA_INT_MAX)
+   blue = CHV_MAX_GAMMA;
+   green_int = _GAMMA_INT_PART(green);
+   if (green_int > GAMMA_INT_MAX)
+   green = CHV_MAX_GAMMA;
+   red_int = _GAMMA_INT_PART(red);
+   if (red_int > GAMMA_INT_MAX)
+   red = CHV_MAX_GAMMA;
+
+   blue_fract = _GAMMA_FRACT_PART(blue);
+   green_fract = _GAMMA_FRACT_PART(green);
+   red_fract = _GAMMA_FRACT_PART(red);
+
+   blue_fract >>= CHV_DEGAMMA_MSB_SHIFT;
+   green_fract >>= CHV_DEGAMMA_MSB_SHIFT;
+   red_fract >>= CHV_DEGAMMA_MSB_SHIFT;
+
+   /* Green (29:16) and Blue (13:0) in DWORD1 */
+   word = green_fract;
+   word <<= CHV_DEGAMMA_GREEN_SHIFT;
+   word = word | blue;
+   I915_WRITE(cgm_degamma_reg, word);
+
+   cgm_degamma_reg += 4;
+
+   /* Red (13:0) to be written to DWORD2 */
+   word = red_fract;
+   

[PATCH 15/23] drm/i915: CHV: Pipe level Gamma correction

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

CHV/BSW platform supports two different pipe level gamma
correction modes, which are:
1. Legacy 8-bit mode
2. 10-bit CGM (Color Gamut Mapping) mode

This patch does the following:
1. Attaches Gamma property to CRTC
3. Adds the core Gamma correction function for CHV/BSW
4. Adds Gamma correction macros

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/i915_reg.h|  12 +++
 drivers/gpu/drm/i915/intel_color_manager.c | 127 +
 drivers/gpu/drm/i915/intel_color_manager.h |  21 +
 3 files changed, 160 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 67bf205..93aa1f9 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7977,4 +7977,16 @@ enum skl_disp_power_wells {
 #define GEN9_VEBOX_MOCS_0  0xcb00  /* Video MOCS base register*/
 #define GEN9_BLT_MOCS_00xcc00  /* Blitter MOCS base register*/

+/* Color Management */
+#define PIPEA_CGM_CONTROL  (VLV_DISPLAY_BASE + 0x67A00)
+#define PIPEB_CGM_CONTROL  (VLV_DISPLAY_BASE + 0x69A00)
+#define PIPEC_CGM_CONTROL  (VLV_DISPLAY_BASE + 0x6BA00)
+#define PIPEA_CGM_GAMMA(VLV_DISPLAY_BASE + 0x67000)
+#define PIPEB_CGM_GAMMA(VLV_DISPLAY_BASE + 0x69000)
+#define PIPEC_CGM_GAMMA(VLV_DISPLAY_BASE + 0x6B000)
+#define _PIPE_CGM_CONTROL(pipe) \
+   (_PIPE3(pipe, PIPEA_CGM_CONTROL, PIPEB_CGM_CONTROL, PIPEC_CGM_CONTROL))
+#define _PIPE_GAMMA_BASE(pipe) \
+   (_PIPE3(pipe, PIPEA_CGM_GAMMA, PIPEB_CGM_GAMMA, PIPEC_CGM_GAMMA))
+
 #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index 2ba3fd7..222924d 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -66,6 +66,127 @@ int intel_color_manager_set_pipe_degamma(struct drm_device 
*dev,
return 0;
 }

+static int chv_set_gamma(struct drm_device *dev, struct drm_property_blob 
*blob,
+ struct drm_crtc *crtc)
+{
+   bool flag = false;
+   enum pipe pipe;
+   u8 red_int, blue_int, green_int;
+   u16 red_fract, green_fract, blue_fract;
+   u32 red, green, blue;
+   u32 cgm_control_reg = 0;
+   u32 cgm_gamma_reg = 0;
+   u32 count = 0, num_samples, word;
+   int ret = 0, length;
+   struct drm_r32g32b32 *correction_values = NULL;
+   struct drm_palette *gamma_data;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+
+   if (WARN_ON(!blob))
+   return -EINVAL;
+
+   gamma_data = (struct drm_palette *)blob->data;
+
+   if (gamma_data->version != GAMMA_DATA_STRUCT_VERSION) {
+   DRM_DEBUG_KMS("Invalid Gamma Data struct version\n");
+   return -EINVAL;
+   }
+
+   pipe = to_intel_crtc(crtc)->pipe;
+   num_samples = gamma_data->num_samples;
+   length = num_samples * sizeof(struct drm_r32g32b32);
+
+   switch (num_samples) {
+   case 0:
+
+   /* Disable Gamma functionality on Pipe - CGM Block */
+   cgm_control_reg = I915_READ(_PIPE_CGM_CONTROL(pipe));
+   cgm_control_reg &= ~CGM_GAMMA_EN;
+   I915_WRITE(_PIPE_CGM_CONTROL(pipe), cgm_control_reg);
+
+   DRM_DEBUG_DRIVER("Gamma disabled on Pipe %c\n",
+   pipe_name(pipe));
+   ret = 0;
+   break;
+
+   case CHV_8BIT_GAMMA_MAX_VALS:
+   case CHV_10BIT_GAMMA_MAX_VALS:
+
+   count = 0;
+   cgm_gamma_reg = _PIPE_GAMMA_BASE(pipe);
+   correction_values = (struct drm_r32g32b32 *)_data->lut;
+
+   while (count < num_samples) {
+   blue = correction_values[count].b32;
+   green = correction_values[count].g32;
+   red = correction_values[count].r32;
+
+   blue_int = _GAMMA_INT_PART(blue);
+   if (blue_int > GAMMA_INT_MAX)
+   blue = CHV_MAX_GAMMA;
+
+   green_int = _GAMMA_INT_PART(green);
+   if (green_int > GAMMA_INT_MAX)
+   green = CHV_MAX_GAMMA;
+
+   red_int = _GAMMA_INT_PART(red);
+   if (red_int > GAMMA_INT_MAX)
+   red = CHV_MAX_GAMMA;
+
+   blue_fract = _GAMMA_FRACT_PART(blue);
+   green_fract = _GAMMA_FRACT_PART(green);
+   red_fract = _GAMMA_FRACT_PART(red);
+
+   blue_fract >>= CHV_10BIT_GAMMA_MSB_SHIFT;
+   green_fract >>= CHV_10BIT_GAMMA_MSB_SHIFT;
+   red_fract >>= CHV_10BIT_GAMMA_MSB_SHIFT;
+
+   

[PATCH 14/23] drm/i915: CHV: Load degamma color correction values

2015-09-17 Thread Shashank Sharma
DRM color manager allows the driver to showcase its best color
correction capabilities using the cm_crtc_palette_capabilities_property.

This patch adds no of coefficitents for degamma color correction
modes possible in CHV, in device info structure, which is:
CGM Degamma(10 bit, CGM HW unit):- 65 coeff

These values will be loaded in cm_crtc_palette_capabilities_property
during the CRTC init section, by color manager's attach function.

Signed-off-by: Shashank Sharma 
---
 drivers/gpu/drm/i915/i915_drv.c| 1 +
 drivers/gpu/drm/i915/intel_color_manager.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 04a8e45..03db841 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -351,6 +351,7 @@ static const struct intel_device_info intel_cherryview_info 
= {
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.num_samples_after_ctm = CHV_10BIT_GAMMA_MAX_VALS,
+   .num_samples_before_ctm = CHV_DEGAMMA_MAX_VALS,
.is_valleyview = 1,
.display_mmio_offset = VLV_DISPLAY_BASE,
GEN_CHV_PIPEOFFSETS,
diff --git a/drivers/gpu/drm/i915/intel_color_manager.h 
b/drivers/gpu/drm/i915/intel_color_manager.h
index 99ef646..402b825 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.h
+++ b/drivers/gpu/drm/i915/intel_color_manager.h
@@ -30,3 +30,4 @@

 #define COLOR_STRUCT_VERSION   1
 #define CHV_10BIT_GAMMA_MAX_VALS   257
+#define CHV_DEGAMMA_MAX_VALS   65
-- 
1.9.1



[PATCH 13/23] drm/i915: CHV: Load gamma color correction values

2015-09-17 Thread Shashank Sharma
DRM color manager allows the driver to showcase its best color
correction capabilities using the cm_crtc_palette_capabilities_property.
Driver loads the no. of coefficients for various color correction
as per the platform, during the init time.

This patch adds no of coefficitents for best gamma color correction
modes possible in CHV, in device info structure, which is:
Gamma(10 bit, CGM HW unit):- 257 coeff
These values will be loaded in cm_crtc_palette_capabilities_property
during the CRTC init section, by color manager's attach function.

Signed-off-by: Shashank Sharma 
---
 drivers/gpu/drm/i915/i915_drv.c| 2 ++
 drivers/gpu/drm/i915/intel_color_manager.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index bdec64c..04a8e45 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -34,6 +34,7 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include "intel_drv.h"
+#include "intel_color_manager.h"

 #include 
 #include 
@@ -349,6 +350,7 @@ static const struct intel_device_info intel_cherryview_info 
= {
.gen = 8, .num_pipes = 3,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+   .num_samples_after_ctm = CHV_10BIT_GAMMA_MAX_VALS,
.is_valleyview = 1,
.display_mmio_offset = VLV_DISPLAY_BASE,
GEN_CHV_PIPEOFFSETS,
diff --git a/drivers/gpu/drm/i915/intel_color_manager.h 
b/drivers/gpu/drm/i915/intel_color_manager.h
index 1a42244..99ef646 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.h
+++ b/drivers/gpu/drm/i915/intel_color_manager.h
@@ -29,3 +29,4 @@
 #include "i915_drv.h"

 #define COLOR_STRUCT_VERSION   1
+#define CHV_10BIT_GAMMA_MAX_VALS   257
-- 
1.9.1



[PATCH 12/23] drm/i915: Add pipe CSC correction handlers

2015-09-17 Thread Shashank Sharma
This patch adds set_property and get_property handlers for pipe
level CSC color correction for CHV/BSW platform. The set
function just attaches the CSC blob to CRTC state, that later
gets committed using atomic path.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/intel_atomic.c|  8 
 drivers/gpu/drm/i915/intel_color_manager.c | 19 +++
 drivers/gpu/drm/i915/intel_drv.h   |  3 +++
 3 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index b504b4f..57eafca 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -325,6 +325,9 @@ int intel_crtc_atomic_set_property(struct drm_crtc *crtc,
if (property == config->cm_palette_before_ctm_property)
return intel_color_manager_set_pipe_degamma(dev, state,
>base, val);
+   if (property == config->cm_ctm_property)
+   return intel_color_manager_set_pipe_csc(dev, state,
+   >base, val);

DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
return -EINVAL;
@@ -350,6 +353,11 @@ int intel_crtc_atomic_get_property(struct drm_crtc *crtc,
goto found;
}

+   if (property == config->cm_ctm_property) {
+   *val = (state->ctm_blob) ? state->ctm_blob->base.id : 0;
+   goto found;
+   }
+
DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
return -EINVAL;

diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index 8890b09..2ba3fd7 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -27,6 +27,25 @@

 #include "intel_color_manager.h"

+int intel_color_manager_set_pipe_csc(struct drm_device *dev,
+   struct drm_crtc_state *crtc_state,
+   struct drm_mode_object *obj, uint32_t blob_id)
+{
+   struct drm_property_blob *blob;
+
+   blob = drm_property_lookup_blob(dev, blob_id);
+   if (!blob) {
+   DRM_ERROR("Invalid Blob ID\n");
+   return -EINVAL;
+   }
+
+   if (crtc_state->ctm_blob)
+   drm_property_unreference_blob(crtc_state->ctm_blob);
+
+   crtc_state->ctm_blob = blob;
+   return 0;
+}
+
 int intel_color_manager_set_pipe_degamma(struct drm_device *dev,
struct drm_crtc_state *crtc_state,
struct drm_mode_object *obj, uint32_t blob_id)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0298dd0..4d571a2f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1473,4 +1473,7 @@ int intel_color_manager_set_pipe_gamma(struct drm_device 
*dev,
 int intel_color_manager_set_pipe_degamma(struct drm_device *dev,
struct drm_crtc_state *crtc_state,
struct drm_mode_object *obj, uint32_t blob_id);
+int intel_color_manager_set_pipe_csc(struct drm_device *dev,
+   struct drm_crtc_state *crtc_state,
+   struct drm_mode_object *obj, uint32_t blob_id);
 #endif /* __INTEL_DRV_H__ */
-- 
1.9.1



[PATCH 11/23] drm/i915: Add pipe deGamma correction handlers

2015-09-17 Thread Shashank Sharma
This patch adds set_property and get_property handlers for deGamma
color correction capability at Pipe level.

Set function just attaches the deGamma correction blob to CRTC state, which
will be later committed in the atomic commit path.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/intel_atomic.c| 10 ++
 drivers/gpu/drm/i915/intel_color_manager.c | 20 
 drivers/gpu/drm/i915/intel_drv.h   |  4 +++-
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index 0b61fef..b504b4f 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -322,6 +322,10 @@ int intel_crtc_atomic_set_property(struct drm_crtc *crtc,
return intel_color_manager_set_pipe_gamma(dev, state,
>base, val);

+   if (property == config->cm_palette_before_ctm_property)
+   return intel_color_manager_set_pipe_degamma(dev, state,
+   >base, val);
+
DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
return -EINVAL;
 }
@@ -340,6 +344,12 @@ int intel_crtc_atomic_get_property(struct drm_crtc *crtc,
goto found;
}

+   if (property == config->cm_palette_before_ctm_property) {
+   *val = (state->palette_before_ctm_blob) ?
+   state->palette_before_ctm_blob->base.id : 0;
+   goto found;
+   }
+
DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
return -EINVAL;

diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index 9421bb6..8890b09 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -27,6 +27,26 @@

 #include "intel_color_manager.h"

+int intel_color_manager_set_pipe_degamma(struct drm_device *dev,
+   struct drm_crtc_state *crtc_state,
+   struct drm_mode_object *obj, uint32_t blob_id)
+{
+   struct drm_property_blob *blob;
+
+   blob = drm_property_lookup_blob(dev, blob_id);
+   if (!blob) {
+   DRM_ERROR("Invalid Blob ID\n");
+   return -EINVAL;
+   }
+
+   if (crtc_state->palette_before_ctm_blob)
+   drm_property_unreference_blob(
+   crtc_state->palette_before_ctm_blob);
+
+   crtc_state->palette_before_ctm_blob = blob;
+   return 0;
+}
+
 int intel_color_manager_set_pipe_gamma(struct drm_device *dev,
struct drm_crtc_state *crtc_state,
struct drm_mode_object *obj, uint32_t blob_id)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d0193e2..0298dd0 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1470,5 +1470,7 @@ extern const struct drm_plane_helper_funcs 
intel_plane_helper_funcs;
 int intel_color_manager_set_pipe_gamma(struct drm_device *dev,
struct drm_crtc_state *crtc_state,
struct drm_mode_object *obj, uint32_t blob_id);
-
+int intel_color_manager_set_pipe_degamma(struct drm_device *dev,
+   struct drm_crtc_state *crtc_state,
+   struct drm_mode_object *obj, uint32_t blob_id);
 #endif /* __INTEL_DRV_H__ */
-- 
1.9.1



[PATCH 10/23] drm/i915: Add gamma correction handlers

2015-09-17 Thread Shashank Sharma
I915 driver registers gamma correction as palette correction
property with DRM layer. This patch adds set_property() and get_property()
handlers for pipe level gamma correction.

The set function attaches the Gamma correction blob to CRTC state, these
values will be committed during atomic commit.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/intel_atomic.c| 20 
 drivers/gpu/drm/i915/intel_color_manager.c | 21 +
 drivers/gpu/drm/i915/intel_drv.h   |  5 +
 3 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index 500d2998..0b61fef 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -315,6 +315,13 @@ int intel_crtc_atomic_set_property(struct drm_crtc *crtc,
   struct drm_property *property,
   uint64_t val)
 {
+   struct drm_device *dev = crtc->dev;
+   struct drm_mode_config *config = >mode_config;
+
+   if (property == config->cm_palette_after_ctm_property)
+   return intel_color_manager_set_pipe_gamma(dev, state,
+   >base, val);
+
DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
return -EINVAL;
 }
@@ -324,6 +331,19 @@ int intel_crtc_atomic_get_property(struct drm_crtc *crtc,
   struct drm_property *property,
   uint64_t *val)
 {
+   struct drm_device *dev = crtc->dev;
+   struct drm_mode_config *config = >mode_config;
+
+   if (property == config->cm_palette_after_ctm_property) {
+   *val = (state->palette_after_ctm_blob) ?
+   state->palette_after_ctm_blob->base.id : 0;
+   goto found;
+   }
+
DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
return -EINVAL;
+
+found:
+   DRM_DEBUG_KMS("Found property %s\n", property->name);
+   return 0;
 }
diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index 77f58f2..9421bb6 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -27,6 +27,27 @@

 #include "intel_color_manager.h"

+int intel_color_manager_set_pipe_gamma(struct drm_device *dev,
+   struct drm_crtc_state *crtc_state,
+   struct drm_mode_object *obj, uint32_t blob_id)
+{
+   struct drm_property_blob *blob;
+
+   blob = drm_property_lookup_blob(dev, blob_id);
+   if (!blob) {
+   DRM_DEBUG_KMS("Invalid Blob ID\n");
+   return -EINVAL;
+   }
+
+   if (crtc_state->palette_after_ctm_blob)
+   drm_property_unreference_blob(
+   crtc_state->palette_after_ctm_blob);
+
+   /* Attach the blob to be committed in state */
+   crtc_state->palette_after_ctm_blob = blob;
+   return 0;
+}
+
 int get_pipe_capabilities(struct drm_device *dev,
struct drm_palette_caps *palette_caps, struct drm_crtc *crtc)
 {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e27e754..d0193e2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1466,4 +1466,9 @@ void intel_plane_destroy_state(struct drm_plane *plane,
   struct drm_plane_state *state);
 extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;

+/* intel_color_manager.c */
+int intel_color_manager_set_pipe_gamma(struct drm_device *dev,
+   struct drm_crtc_state *crtc_state,
+   struct drm_mode_object *obj, uint32_t blob_id);
+
 #endif /* __INTEL_DRV_H__ */
-- 
1.9.1



[PATCH 09/23] drm/i915: Register pipe color capabilities

2015-09-17 Thread Shashank Sharma
DRM color manager contains these color properties:

1. "crtc_palette_capabilities_property": to allow a
core driver to load and showcase its color correction
capabilities to user space.
2. "ctm": Color transformation matrix property, where a
color transformation matrix of 9 correction values gets
applied as correction.
3. "palette_before_ctm": for corrections which get applied
beore color transformation matrix correction.
4. "palette_after_ctm": for corrections which get applied
after color transformation matrix correction.

Intel color manager registers:
1. Gamma correction property as "palette_after_ctm" property
2. Degamma correction capability as "palette_bafore_ctm" property
capability as "palette_after_ctm" DRM color property hook.
3. CSC as "ctm" property.

This patch does the following:
1. Add a function which loads the platform's color correction
capabilities in the cm_crtc_palette_capabilities_property structure.
2. Attaches the cm_crtc_palette_capabilities_property to every CRTC
getting initiaized.
3. Adds two new parameters "num_samples_after_ctm" and
"num_samples_before_ctm" in intel_device_info as gamma and
degamma coefficients vary per platform basis.

Signed-off-by: Shashank Sharma 
---
 drivers/gpu/drm/i915/i915_drv.h|  2 ++
 drivers/gpu/drm/i915/intel_color_manager.c | 45 ++
 drivers/gpu/drm/i915/intel_color_manager.h |  2 ++
 3 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3bf8a9b..22de2cb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -798,6 +798,8 @@ struct intel_device_info {
u8 num_sprites[I915_MAX_PIPES];
u8 gen;
u8 ring_mask; /* Rings supported by the HW */
+   u16 num_samples_after_ctm;
+   u16 num_samples_before_ctm;
DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
/* Register offsets for the various display pipes and transcoders */
int pipe_offsets[I915_MAX_TRANSCODERS];
diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
index 7357d99..77f58f2 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -27,7 +27,52 @@

 #include "intel_color_manager.h"

+int get_pipe_capabilities(struct drm_device *dev,
+   struct drm_palette_caps *palette_caps, struct drm_crtc *crtc)
+{
+   struct drm_property_blob *blob;
+
+   /*
+* This function loads best capability for gamma correction
+* For example:
+* CHV best Gamma correction (CGM unit, 10 bit)
+* has 257 entries, best degamma is 65 entries
+*/
+   palette_caps->version = COLOR_STRUCT_VERSION;
+   palette_caps->num_samples_after_ctm =
+   INTEL_INFO(dev)->num_samples_after_ctm;
+   palette_caps->num_samples_before_ctm =
+   INTEL_INFO(dev)->num_samples_before_ctm;
+   blob = drm_property_create_blob(dev, sizeof(struct drm_palette_caps),
+   (const void *) palette_caps);
+   if (IS_ERR_OR_NULL(blob)) {
+   DRM_ERROR("Create blob for capabilities failed\n");
+   return PTR_ERR(blob);
+   }
+
+   return blob->base.id;
+}
+
 void intel_attach_color_properties_to_crtc(struct drm_device *dev,
struct drm_mode_object *mode_obj)
 {
+   struct drm_mode_config *config = >mode_config;
+   struct drm_palette_caps *palette_caps;
+   struct drm_crtc *crtc;
+   int capabilities_blob_id;
+
+   crtc = obj_to_crtc(mode_obj);
+   palette_caps = kzalloc(sizeof(struct drm_palette_caps),
+   GFP_KERNEL);
+   capabilities_blob_id = get_pipe_capabilities(dev,
+   palette_caps, crtc);
+
+   if (config->cm_crtc_palette_capabilities_property) {
+   drm_object_attach_property(mode_obj,
+   config->cm_crtc_palette_capabilities_property,
+   capabilities_blob_id);
+   DRM_DEBUG_DRIVER("Capabilities attached to CRTC\n");
+   }
+
+   kfree(palette_caps);
 }
diff --git a/drivers/gpu/drm/i915/intel_color_manager.h 
b/drivers/gpu/drm/i915/intel_color_manager.h
index 04c921d..1a42244 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.h
+++ b/drivers/gpu/drm/i915/intel_color_manager.h
@@ -27,3 +27,5 @@
 #include 
 #include 
 #include "i915_drv.h"
+
+#define COLOR_STRUCT_VERSION   1
-- 
1.9.1



[PATCH 08/23] drm/i915: Create color management files

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

This patch create new files intel_color_manager.c which
will contain the core color correction code for I915 driver
and its header intel_color_manager.h

The per color property patches coming up in this patch series
will fill the appropriate functions in this file.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/Makefile  |  3 ++-
 drivers/gpu/drm/i915/intel_color_manager.c | 33 ++
 drivers/gpu/drm/i915/intel_color_manager.h | 29 ++
 3 files changed, 64 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/intel_color_manager.c
 create mode 100644 drivers/gpu/drm/i915/intel_color_manager.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 44d290a..56caf9e 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -64,7 +64,8 @@ i915-y += intel_audio.o \
  intel_overlay.o \
  intel_psr.o \
  intel_sideband.o \
- intel_sprite.o
+ intel_sprite.o \
+ intel_color_manager.o
 i915-$(CONFIG_ACPI)+= intel_acpi.o intel_opregion.o
 i915-$(CONFIG_DRM_FBDEV_EMULATION) += intel_fbdev.o

diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
b/drivers/gpu/drm/i915/intel_color_manager.c
new file mode 100644
index 000..7357d99
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Shashank Sharma 
+ * Kausal Malladi 
+ */
+
+#include "intel_color_manager.h"
+
+void intel_attach_color_properties_to_crtc(struct drm_device *dev,
+   struct drm_mode_object *mode_obj)
+{
+}
diff --git a/drivers/gpu/drm/i915/intel_color_manager.h 
b/drivers/gpu/drm/i915/intel_color_manager.h
new file mode 100644
index 000..04c921d
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_color_manager.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Shashank Sharma 
+ * Kausal Malladi 
+ */
+#include 
+#include 
+#include "i915_drv.h"
-- 
1.9.1



[PATCH 07/23] drm/i915: Add atomic get property interface for CRTC

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

This patch adds atomic get property interface for Intel CRTC. This
interface will be used for get operation on any non-core DRM properties.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/intel_atomic.c  | 9 +
 drivers/gpu/drm/i915/intel_display.c | 1 +
 drivers/gpu/drm/i915/intel_drv.h | 4 
 3 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index d5b7eb1..500d2998 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -318,3 +318,12 @@ int intel_crtc_atomic_set_property(struct drm_crtc *crtc,
DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
return -EINVAL;
 }
+
+int intel_crtc_atomic_get_property(struct drm_crtc *crtc,
+  const struct drm_crtc_state *state,
+  struct drm_property *property,
+  uint64_t *val)
+{
+   DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
+   return -EINVAL;
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 444ea30..010acca 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13194,6 +13194,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
.page_flip = intel_crtc_page_flip,
.set_property = drm_atomic_helper_crtc_set_property,
.atomic_set_property = intel_crtc_atomic_set_property,
+   .atomic_get_property = intel_crtc_atomic_get_property,
.atomic_duplicate_state = intel_crtc_duplicate_state,
.atomic_destroy_state = intel_crtc_destroy_state,
 };
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 510f559..e27e754 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1454,6 +1454,10 @@ int intel_crtc_atomic_set_property(struct drm_crtc 
*plane,
   struct drm_crtc_state *state,
   struct drm_property *property,
   uint64_t val);
+int intel_crtc_atomic_get_property(struct drm_crtc *plane,
+  const struct drm_crtc_state *state,
+  struct drm_property *property,
+  uint64_t *val);

 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
-- 
1.9.1



[PATCH 06/23] drm/i915: Add atomic set property interface for CRTC

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

This patch adds atomic set property interface for Intel CRTC. This
interface will be used for set operation on any DRM properties.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/i915/intel_atomic.c  | 9 +
 drivers/gpu/drm/i915/intel_display.c | 2 ++
 drivers/gpu/drm/i915/intel_drv.h | 4 
 3 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index f1975f2..d5b7eb1 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -309,3 +309,12 @@ void intel_atomic_state_clear(struct drm_atomic_state *s)
drm_atomic_state_default_clear(>base);
state->dpll_set = false;
 }
+
+int intel_crtc_atomic_set_property(struct drm_crtc *crtc,
+  struct drm_crtc_state *state,
+  struct drm_property *property,
+  uint64_t val)
+{
+   DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
+   return -EINVAL;
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index fc00867..444ea30 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13192,6 +13192,8 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = intel_crtc_destroy,
.page_flip = intel_crtc_page_flip,
+   .set_property = drm_atomic_helper_crtc_set_property,
+   .atomic_set_property = intel_crtc_atomic_set_property,
.atomic_duplicate_state = intel_crtc_duplicate_state,
.atomic_destroy_state = intel_crtc_destroy_state,
 };
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 02a755a..510f559 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1450,6 +1450,10 @@ intel_atomic_get_crtc_state(struct drm_atomic_state 
*state,
 int intel_atomic_setup_scalers(struct drm_device *dev,
struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state);
+int intel_crtc_atomic_set_property(struct drm_crtc *plane,
+  struct drm_crtc_state *state,
+  struct drm_property *property,
+  uint64_t val);

 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
-- 
1.9.1



[PATCH 05/23] drm: Add structure to set/get a CTM color property

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

Color Manager framework defines a color correction property for color
space transformation and Gamut mapping. This property is called CTM (Color
Transformation Matrix).

This patch adds a new structure in DRM layer for CTM.
This structure can be used by all user space agents to
configure CTM coefficients for color correction.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 include/uapi/drm/drm.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index f72b916..9580772 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -867,6 +867,18 @@ struct drm_palette {
struct drm_r32g32b32 lut[0];
 };

+struct drm_ctm {
+   /* Structure version. Should be 1 currently */
+   __u32 version;
+   /*
+* Each value is in S31.32 format.
+* This is 3x3 matrix in row major format.
+* Integer part will be clipped to nearest
+* max/min boundary as supported by the HW platform.
+*/
+   __s64 ctm_coeff[9];
+};
+
 /* typedef area */
 #ifndef __KERNEL__
 typedef struct drm_clip_rect drm_clip_rect_t;
-- 
1.9.1



[PATCH 04/23] drm: Add drm structures for palette color property

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

This patch adds new structures in DRM layer for Palette color
correction.These structures will be used by user space agents
to configure appropriate number of samples and Palette LUT for
a platform.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 include/uapi/drm/drm.h | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index e3c642f..f72b916 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -840,6 +840,33 @@ struct drm_palette_caps {
__u32 num_samples_after_ctm;
 };

+struct drm_r32g32b32 {
+   /*
+* Data is in U8.24 fixed point format.
+* All platforms support values within [0, 1.0] range,
+* for Red, Green and Blue colors.
+*/
+   __u32 r32;
+   __u32 g32;
+   __u32 b32;
+};
+
+struct drm_palette {
+   /* Structure version. Should be 1 currently */
+   __u32 version;
+   /*
+* This has to be a supported value during get call.
+* Feature will be disabled if this is 0 while set
+*/
+   __u32 num_samples;
+   /*
+* Starting of palette LUT in R32G32B32 format.
+* Each of RGB value is in U8.24 fixed point format.
+* Actual number of samples will depend upon num_samples
+*/
+   struct drm_r32g32b32 lut[0];
+};
+
 /* typedef area */
 #ifndef __KERNEL__
 typedef struct drm_clip_rect drm_clip_rect_t;
-- 
1.9.1



[PATCH 03/23] drm: Add color correction blobs in CRTC state

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

This patch adds new variables in CRTC state, to hold respective color
correction blobs. These blobs will be required during the atomic commit
for writing the color correction values in correction registers.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/drm_atomic_helper.c | 12 
 include/drm/drm_crtc.h  |  5 +
 2 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 94d6c8e..1fe91ee 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2168,6 +2168,12 @@ void __drm_atomic_helper_crtc_duplicate_state(struct 
drm_crtc *crtc,

if (state->mode_blob)
drm_property_reference_blob(state->mode_blob);
+   if (state->ctm_blob)
+   drm_property_reference_blob(state->ctm_blob);
+   if (state->palette_after_ctm_blob)
+   drm_property_reference_blob(state->palette_after_ctm_blob);
+   if (state->palette_before_ctm_blob)
+   drm_property_reference_blob(state->palette_before_ctm_blob);
state->mode_changed = false;
state->active_changed = false;
state->planes_changed = false;
@@ -2213,6 +2219,12 @@ void __drm_atomic_helper_crtc_destroy_state(struct 
drm_crtc *crtc,
 {
if (state->mode_blob)
drm_property_unreference_blob(state->mode_blob);
+   if (state->ctm_blob)
+   drm_property_unreference_blob(state->ctm_blob);
+   if (state->palette_after_ctm_blob)
+   drm_property_unreference_blob(state->palette_after_ctm_blob);
+   if (state->palette_before_ctm_blob)
+   drm_property_unreference_blob(state->palette_before_ctm_blob);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c35531e..fcbe682 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -302,6 +302,11 @@ struct drm_crtc_state {
/* blob property to expose current mode to atomic userspace */
struct drm_property_blob *mode_blob;

+   /* blob properties to hold the color properties' blobs */
+   struct drm_property_blob *palette_before_ctm_blob;
+   struct drm_property_blob *palette_after_ctm_blob;
+   struct drm_property_blob *ctm_blob;
+
struct drm_pending_vblank_event *event;

struct drm_atomic_state *state;
-- 
1.9.1



[PATCH 02/23] drm: Add structure for querying palette color capabilities

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

The DRM color management framework is targeting various hardware
platforms and drivers. Different platforms can have different color
correction and enhancement capabilities.

A commom user space application can query these capabilities using the
DRM property interface. Each driver can fill this property with its
platform's palette color capabilities.

This patch adds new structure in DRM layer for querying palette color
capabilities. This structure will be used by all user space
agents to configure appropriate color configurations.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 include/uapi/drm/drm.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 3801584..e3c642f 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -829,6 +829,17 @@ struct drm_event_vblank {
__u32 reserved;
 };

+struct drm_palette_caps {
+   /* Structure version. Should be 1 currently */
+   __u32 version;
+   /* For padding and future use */
+   __u32 reserved;
+   /* This may be 0 if not supported. e.g. plane palette or VLV pipe */
+   __u32 num_samples_before_ctm;
+   /* This will be non-zero for pipe. May be zero for planes on some HW */
+   __u32 num_samples_after_ctm;
+};
+
 /* typedef area */
 #ifndef __KERNEL__
 typedef struct drm_clip_rect drm_clip_rect_t;
-- 
1.9.1



[PATCH 01/23] drm: Create Color Management DRM properties

2015-09-17 Thread Shashank Sharma
From: Kausal Malladi 

Color Management is an extension to Kernel display framework. It allows
abstraction of hardware color correction and enhancement capabilities by
virtue of DRM properties.

This patch initializes color management framework by :
1. Introducing new pointers in DRM mode_config structure to
   carry CTM and Palette color correction properties.
2. Creating these DRM properties in DRM standard properties creation
   sequence.

Signed-off-by: Shashank Sharma 
Signed-off-by: Kausal Malladi 
---
 drivers/gpu/drm/drm_crtc.c | 26 ++
 include/drm/drm_crtc.h |  6 ++
 2 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 9b9c4b4..d809c67 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1472,6 +1472,32 @@ static int drm_mode_create_standard_properties(struct 
drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_mode_id = prop;

+   /* Color Management properties */
+   prop = drm_property_create(dev,
+   DRM_MODE_PROP_BLOB | DRM_MODE_PROP_IMMUTABLE,
+   "CRTC_PALETTE_CAPABILITIES", 0);
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.cm_crtc_palette_capabilities_property = prop;
+
+   prop = drm_property_create(dev,
+   DRM_MODE_PROP_BLOB, "PALETTE_AFTER_CTM", 0);
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.cm_palette_after_ctm_property = prop;
+
+   prop = drm_property_create(dev,
+   DRM_MODE_PROP_BLOB, "PALETTE_BEFORE_CTM", 0);
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.cm_palette_before_ctm_property = prop;
+
+   prop = drm_property_create(dev,
+   DRM_MODE_PROP_BLOB, "CTM", 0);
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.cm_ctm_property = prop;
+
return 0;
 }

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c0366e9..c35531e 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1153,6 +1153,12 @@ struct drm_mode_config {
struct drm_property *suggested_x_property;
struct drm_property *suggested_y_property;

+   /* Color Management Properties */
+   struct drm_property *cm_crtc_palette_capabilities_property;
+   struct drm_property *cm_palette_before_ctm_property;
+   struct drm_property *cm_palette_after_ctm_property;
+   struct drm_property *cm_ctm_property;
+
/* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow;

-- 
1.9.1



[PATCH 00/23] Color Management for DRM

2015-09-17 Thread Shashank Sharma
This patch set adds Color Manager implementation in DRM layer. Color Manager
is an extension in DRM framework to support color correction/enhancement.

Various Hardware platforms can support several color correction capabilities.
Color Manager provides abstraction of these capabilities and allows a user
space UI agent to correct/enhance the display using the DRM property interface.

How is this going to work?
==
1. This patch series adds a few new properties in DRM framework. These 
properties are:
a. color_capabilities property (type blob)
b. Color Transformation Matrix property for corrections like CSC 
(called CTM, type blob)
c. Palette correction properties for corrections like gamma fixup 
(called palette_correction, type blob) 
2. Also, this patch series adds few structures to indicate specifications of a 
property like size, no_of_samples for correction etc.
3. These properties are present in mode_config.
4. When the platform's display driver loads, it fills up the values of 
color_capabilities property using the standard structures (added in step 2).
   For example, Intel's I915 driver adds following color correction 
capabilities:
a. gamma correction capability as palette correction property, with 257 
correction coefficients and a max/min value
b. csc correction capability as CTM correction property, with 3x3 
transformation matrix values and max/min values 
5. Now when userspace comes up, it queries the platform's color capabilities by 
doing a get_property() on color_capabilities DRM property
6. Reading the blob, the userspace understands the color capabilities of the 
platform.
   For example, userspace will understand it can support:
a. palette_correction with 257 coefficients
b. CSC correction with 3x3 = 9 values 
7. To set color correction values, userspace:
a. creates a blob using the create_blob_ioctl in standard 
palette_correction structure format, with the correction values
b. calls the set_property_ioctl with the blob_id as value for the 
property 
8. Driver refers to the blob, gets the correction values and applies the 
correction in HW.
9. To get currently applied color correction values, userspace:
a. calls a get_property_ioctl on that color property
b. gets the blob_id for the currently applied correction from DRM 
infrastructure
c. gets the blob using get_blob_ioctl and hence the currently applied 
values

That's all! :)

About the patch series:
===
The patch series first adds the color management support in DRM layer.
Then it adds the color management framework in I915 layer. 
After that, it implements platform specific core color correction functios. 

Intel color manager registers color correction with DRM color manager in this 
way:
 - CSC transformation is registered as CTM DRM property
 - Gamma correction is registered as palette_after_ctm DRM property
 - Degamma correction is registered as palette_before_ctm DRM property

Our thanks to all the reviewers who have given valuable comments in terms
of design and implementation to our previous sets of patches. Special mention
of thanks should go to Matt Roper for all his inputs/suggestions in 
implementation
of this module, using DRM atomic CRTC commit path.

V2: Worked on review comments from Matt, Jim, Thierry, Rob.
V3: Worked on review comments from Matt, Jim, Rob:
 - Jim, Rob:
   
   Re-arranged the whole patch series in the sequence of features, currently:
   First 5 patches add color management support in DRM layer
   Next 7 patches add Intel color management framework in I915 driver
   Next 5 patches add color correction for CHV (gamma, degamma and CSC)
   Next 2 patches enable color management, by attaching the properties to 
CRTC(Matt)
   Next 4 patches add color correction for BDW (gamma, degamma)
 - Matt:
   =
   Patch 3: Added refernce/unreference for blob
   Patch 7: return -EINVAL and added debug message
   Patch 8: check for valid blob, from create blob
moved call to intel_crtc_attach_color_prop in the end of full 
implementation (CHV)
   Patch 9: DRM_ERROR->DRM_DEBUG for NULL blob case
   Patch 13: Added static for internal functions
   Patch 20-24: renamed gen9_* functions to bdw_*
   Added new variables in device_info structure num_samples_after_ctm and 
num_samples_before_ctm
   Added new function in patch 8 to load capabilities based on device_info 
across all platforms

Shashank Sharma (23):
  drm: Create Color Management DRM properties
  drm: Add structure for querying palette color capabilities
  drm: Add color correction blobs in CRTC state
  drm: Add drm structures for palette color property
  drm: Add structure to set/get a CTM color property
  drm/i915: Add atomic set property interface for CRTC
  drm/i915: Add atomic get property interface for CRTC
  drm/i915: Create color management files
  drm/i915: Register pipe color capabilities