[PATCH 1/4] clk: propagate parent change up one level

2014-06-18 Thread Tomasz Stanislawski
Hi Mike,
Do you have any comments about this patch?
The patch is needed to provide a clean fix for recently
broken support for HDMI on Exynos4210 SoC in mainline.

Regards,
Tomasz Stanislawski


On 05/01/2014 12:19 AM, Tomasz Figa wrote:
> Mike,
> 
> On 08.04.2014 17:45, Tomasz Figa wrote:
>> Hi,
>>
>> On 04.04.2014 16:53, Tomasz Stanislawski wrote:
>>> This patch adds support for propagation of setup of clock's parent one
>>> level
>>> up.
>>>
>>> This feature is helpful when a driver changes topology of its clocks
>>> using
>>> clk_set_parent().  The problem occurs when on one platform/SoC
>>> driver's clock
>>> is located at MUX output but on the other platform/SoC there is a
>>> gated proxy
>>> clock between the MUX and driver's clock.  In such a case, driver's
>>> code has to
>>> be modified to use one clock for enabling and the other clock for
>>> setup of a
>>> parent.
>>>
>>> The code updates are avoided by propagating setup of a parent up one
>>> level.
>>>
>>> Additionally, this patch adds CLK_SET_PARENT_PARENT (sorry for naming)
>>> flag to
>>> inform clk-core that clk_set_parent() should be propagated.
>>>
>>> Signed-off-by: Tomasz Stanislawski 
>>> ---
>>>   drivers/clk/clk.c|6 ++
>>>   include/linux/clk-provider.h |1 +
>>>   2 files changed, 7 insertions(+)
>>>
>>> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
>>> index dff0373..53bbfda 100644
>>> --- a/drivers/clk/clk.c
>>> +++ b/drivers/clk/clk.c
>>> @@ -1737,6 +1737,12 @@ int clk_set_parent(struct clk *clk, struct clk
>>> *parent)
>>>
>>>   /* try finding the new parent index */
>>>   if (parent) {
>>> +if ((clk->flags & CLK_SET_PARENT_PARENT)
>>> +&& clk->num_parents == 1) {
>>> +ret = clk_set_parent(clk->parent, parent);
>>> +goto out;
>>> +}
>>> +
>>>   p_index = clk_fetch_parent_index(clk, parent);
>>>   p_rate = parent->rate;
>>>   if (p_index < 0) {
>>> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
>>> index 5119174..daa0b03 100644
>>> --- a/include/linux/clk-provider.h
>>> +++ b/include/linux/clk-provider.h
>>> @@ -30,6 +30,7 @@
>>>   #define CLK_GET_RATE_NOCACHEBIT(6) /* do not use the cached clk
>>> rate */
>>>   #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate
>>> change */
>>>   #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk
>>> accuracy */
>>> +#define CLK_SET_PARENT_PARENTBIT(9) /* propagate parent change up
>>> one level */
>>>
>>>   struct clk_hw;
>>>   struct dentry;
>>>
>>
>> This would be very useful, at least on Exynos platforms, with
>> mux-div-gate clock paths. PARENT_PARENT sounds a bit funny, though.
>>
>> Reviewed-by: Tomasz Figa 
> 
> Your opinion on this would be greatly appreciated.
> 
> Best regards,
> Tomasz



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

2014-05-07 Thread Tomasz Stanislawski
On 05/07/2014 12:38 PM, Rahul Sharma wrote:
> On 5 May 2014 15:14, Kishon Vijay Abraham I  wrote:
>> Hi,
>>
>> On Wednesday 09 April 2014 03:31 PM, Sylwester Nawrocki wrote:
>>> Hi,
>>>
>>> On 09/04/14 11:12, Rahul Sharma wrote:
>>>> Idea looks good. How about keeping compatible which is independent
>>>> of SoC, something like "samsung,exynos-simple-phy" and provide Reg
>>>> and Bit through phy provider node. This way we can avoid SoC specific
>>>> hardcoding in phy driver and don't need to look into dt bindings for
>>>> each new SoC.
>>>
>>> I believe it is a not recommended approach.
>>
>> Why not? We should try to avoid hard coding in the driver code. Moreover by
>> avoiding hardcoding we can make it a generic driver for single bit PHYs.
>>
> 
> +1.
> 
> @Tomasz, any plans to consider this approach for simple phy driver?
> 
> Regards,
> Rahul Sharma.
> 

Hi Rahul,
Initially, I wanted to make a very generic driver and to add bit and
register (or its offset) attribute to the PHY node.
However, there was a very strong opposition from DT maintainers
to adding any bit related configuration to DT.
The current solution was designed to be a trade-off between
being generic and being accepted :).

Regards,
Tomasz Stanislawski



>> Cheers
>> Kishon
> 



[PATCH 0/2] Add support for sii9234 chip

2014-05-05 Thread Tomasz Stanislawski
On 05/04/2014 01:17 AM, Greg KH wrote:
> On Fri, Apr 11, 2014 at 01:48:28PM +0200, Tomasz Stanislawski wrote:
>> Hi everyone,
>> This patchset adds support for sii9234 HD Mobile Link Bridge.  The chip is 
>> used
>> to convert HDMI signal into MHL.  The driver enables HDMI output on Trats and
>> Trats2 boards.
>>
>> The code is based on the driver [1] developed by:
>>Adam Hampson 
>>Erik Gilling 
>> with additional contributions from:
>>Shankar Bandal 
>>Dharam Kumar 
>>
>> The drivers architecture was greatly simplified and transformed into a form
>> accepted (hopefully) by opensource community.  The main differences from
>> original code are:
>> * using single I2C client instead of 4 subclients
>> * remove all logic non-related to establishing HDMI link
>> * simplify error handling
>> * rewrite state machine in interrupt handler
>> * wakeup and discovery triggered by an extcon event
>> * integrate with Device Tree
>>
>> For now, the driver is added to drivers/misc/ directory because it has 
>> neigher
>> userspace nor kernel interface.  The chip is capable of receiving and
>> processing CEC events, so the driver may export an input device in /dev/ in 
>> the
>> future.  However CEC could be also handled by HDMI driver.
>>
>> I kindly ask for suggestions about the best location for this driver.
> 
> It really is an extcon driver, so why not put it in drivers/extcon?  And
> that might solve any build issues you have if you don't select extcon in
> your .config file and try to build this code :)
> 
> thanks,

Hi Greg,
Thank you for your comments.

As I understand, drivers/extcon contains only extcon providers.
This driver is an extcon client, so mentioned location may not be adequate.

I am surprised that there are no comments about this driver.
Sii9234 chip is present on many exynos based boards/phones
and HDMI subsystem will not work without this code.

Regards,
Tomasz Stanislawski

> 
> greg k-h
> 



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

2014-04-30 Thread Tomasz Stanislawski
Hi Rahul,
I will prepare we v3 version.
Do you want me to add your patches for exynos5?50 to the patchset?
Regards,
Tomasz Stanislawski

On 04/30/2014 08:37 AM, Rahul Sharma wrote:
> Hi Tomasz,
> 
> I have tested your patches for exynos5250 and 5420. Works fine. Are
> you planning to post v3? If you want I can share hand with you for v3.
> 
> Regards,
> Rahul Sharma
> 
> On 9 April 2014 17:17, Andreas Oberritter  wrote:
>> Hello Andrzej,
>>
>> On 09.04.2014 10:37, Andrzej Hajda wrote:
>>>> +static int exynos_phy_probe(struct platform_device *pdev)
>>>> +{
>>>> +const struct of_device_id *of_id = of_match_device(
>>>> +of_match_ptr(exynos_phy_of_match), >dev);
>>>> +const u32 *offsets = of_id->data;
>>>> +int count;
>>>> +struct device *dev = >dev;
>>>> +struct phy **phys;
>>>> +struct resource *res;
>>>> +void __iomem *regs;
>>>> +int i;
>>>> +struct phy_provider *phy_provider;
>>>> +
>>>> +/* count number of phys to create */
>>>> +for (count = 0; offsets[count] != ~0; ++count)
>>>> +;
>>>
>>> count = ARRAY_SIZE(offsets) - 1;
>>
>> u32 *offsets is not an array.
>>
>> Regards,
>> Andreas
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 
>> in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



[PATCHv3 1/5] drm: exynos: hdmi: remove usage of struct s5p_hdmi_platform_data

2014-04-17 Thread Tomasz Stanislawski
Hi Joonyoung,

On 04/17/2014 03:54 AM, Joonyoung Shim wrote:
> Hi Tomasz,
> 
> On 04/17/2014 12:12 AM, Tomasz Stanislawski wrote:
>> This patch continues shift of DRM EXYNOS to DT-only configuration.
>> The usage of the old structure for HDMI's platform data is
>> removed.
>>
>> Signed-off-by: Tomasz Stanislawski 

[snip]

>>   +ret = drm_hdmi_dt_parse(hdata, dev->of_node);
>> +if (ret)
>> +return -EINVAL;
> 
> It's better to return ret value.
> 

I was considering return ret value. However, I preferred to
be consistent with other 'returns' which returns error literals.

Anyway, I will change it to 'return ret'.

Regards,
Tomasz Stanislawski


[PATCHv3 5/5] drm: exynos: hdmi: add support for pixel clock limitation

2014-04-16 Thread Tomasz Stanislawski
Adds support for limitation of maximal pixel clock of HDMI
signal. This feature is needed on boards that contains
lines or bridges with frequency limitations.

Signed-off-by: Tomasz Stanislawski 
---
 .../devicetree/bindings/video/exynos_hdmi.txt  |4 
 drivers/gpu/drm/exynos/exynos_hdmi.c   |   11 +++
 2 files changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt 
b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
index f9187a2..8718f8d 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
@@ -28,6 +28,10 @@ Required properties:
 - ddc: phandle to the hdmi ddc node
 - phy: phandle to the hdmi phy node

+Optional properties:
+- max-pixel-clock: used to limit the maximal pixel clock if a board has lines,
+   connectors or bridges not capable of carring higher frequencies
+
 Example:

hdmi {
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9adbd34..e012ba9 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -194,6 +194,7 @@ struct hdmi_context {
struct hdmi_resources   res;

int hpd_gpio;
+   u32 max_pixel_clock;

enum hdmi_type  type;
 };
@@ -886,6 +887,9 @@ static int hdmi_mode_valid(struct drm_connector *connector,
if (ret)
return MODE_BAD;

+   if (mode->clock * 1000 > hdata->max_pixel_clock)
+   return MODE_CLOCK_HIGH;
+
ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
if (ret < 0)
return MODE_BAD;
@@ -2022,6 +2026,13 @@ static int drm_hdmi_dt_parse(struct hdmi_context *hdata, 
struct device_node *np)
return -ENOENT;
}

+   of_property_read_u32(np, "max-pixel-clock", >max_pixel_clock);
+   if (!hdata->max_pixel_clock) {
+   DRM_INFO("max-pixel-clock is zero, using INF\n");
+   hdata->max_pixel_clock = U32_MAX;
+   }
+
+
return 0;
 }

-- 
1.7.9.5



[PATCHv3 4/5] drm: exynos: add compatibles for HDMI and Mixer chips and exynos4210 SoC

2014-04-16 Thread Tomasz Stanislawski
This patch add proper compatibles for Mixer and HDMI chip
available on exynos4210 SoCs.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c  |7 +++
 drivers/gpu/drm/exynos/exynos_mixer.c |3 +++
 2 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 176e764..9adbd34 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -203,6 +203,10 @@ struct hdmiphy_config {
u8 conf[32];
 };

+struct hdmi_driver_data exynos4210_hdmi_driver_data = {
+   .type   = HDMI_TYPE13,
+};
+
 struct hdmi_driver_data exynos4212_hdmi_driver_data = {
.type   = HDMI_TYPE14,
 };
@@ -2023,6 +2027,9 @@ static int drm_hdmi_dt_parse(struct hdmi_context *hdata, 
struct device_node *np)

 static struct of_device_id hdmi_match_types[] = {
{
+   .compatible = "samsung,exynos4210-hdmi",
+   .data = _hdmi_driver_data,
+   }, {
.compatible = "samsung,exynos5-hdmi",
.data = _hdmi_driver_data,
}, {
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index e3306c8..fd8a9a0 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1187,6 +1187,9 @@ static struct platform_device_id mixer_driver_types[] = {

 static struct of_device_id mixer_match_types[] = {
{
+   .compatible = "samsung,exynos4210-mixer",
+   .data   = _mxr_drv_data,
+   }, {
.compatible = "samsung,exynos5-mixer",
.data   = _mxr_drv_data,
}, {
-- 
1.7.9.5



[PATCHv3 3/5] drm: exynos: mixer: fix using usleep() in atomic context

2014-04-16 Thread Tomasz Stanislawski
This patch fixes calling usleep_range() after taking reg_slock
using spin_lock_irqsave(). The mdelay() is used instead.
Waiting in atomic context is not the best idea in general.
Hopefully, waiting occurs only when Video Processor fails
to reset correctly.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index ce28881..e3306c8 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -615,7 +615,7 @@ static void vp_win_reset(struct mixer_context *ctx)
/* waiting until VP_SRESET_PROCESSING is 0 */
if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
break;
-   usleep_range(1, 12000);
+   mdelay(10);
}
WARN(tries == 0, "failed to reset Video Processor\n");
 }
-- 
1.7.9.5



[PATCHv3 2/5] drm: exynos: hdmi: simplify extracting hpd-gpio from DT

2014-04-16 Thread Tomasz Stanislawski
This patch eliminates redundant checks while retrieving HPD gpio from DT during
HDMI's probe().

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 482ca77..176e764 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2012,15 +2012,12 @@ fail:

 static int drm_hdmi_dt_parse(struct hdmi_context *hdata, struct device_node 
*np)
 {
-   u32 value;
-
-   if (!of_find_property(np, "hpd-gpio", )) {
+   hdata->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
+   if (!gpio_is_valid(hdata->hpd_gpio)) {
DRM_ERROR("no hpd gpio property found\n");
return -ENOENT;
}

-   hdata->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
-
return 0;
 }

-- 
1.7.9.5



[PATCHv3 1/5] drm: exynos: hdmi: remove usage of struct s5p_hdmi_platform_data

2014-04-16 Thread Tomasz Stanislawski
This patch continues shift of DRM EXYNOS to DT-only configuration.
The usage of the old structure for HDMI's platform data is
removed.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   30 --
 1 file changed, 8 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9a6d652..482ca77 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -43,7 +43,6 @@
 #include "exynos_mixer.h"

 #include 
-#include 

 #define get_hdmi_display(dev)  platform_get_drvdata(to_platform_device(dev))
 #define ctx_from_connector(c)  container_of(c, struct hdmi_context, connector)
@@ -2011,28 +2010,18 @@ fail:
return -ENODEV;
 }

-static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
-   (struct device *dev)
+static int drm_hdmi_dt_parse(struct hdmi_context *hdata, struct device_node 
*np)
 {
-   struct device_node *np = dev->of_node;
-   struct s5p_hdmi_platform_data *pd;
u32 value;

-   pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
-   if (!pd)
-   goto err_data;
-
if (!of_find_property(np, "hpd-gpio", )) {
DRM_ERROR("no hpd gpio property found\n");
-   goto err_data;
+   return -ENOENT;
}

-   pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
-
-   return pd;
+   hdata->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);

-err_data:
-   return NULL;
+   return 0;
 }

 static struct of_device_id hdmi_match_types[] = {
@@ -2051,7 +2040,6 @@ static int hdmi_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
struct hdmi_context *hdata;
-   struct s5p_hdmi_platform_data *pdata;
struct resource *res;
const struct of_device_id *match;
struct device_node *ddc_node, *phy_node;
@@ -2061,14 +2049,14 @@ static int hdmi_probe(struct platform_device *pdev)
 if (!dev->of_node)
return -ENODEV;

-   pdata = drm_hdmi_dt_parse_pdata(dev);
-   if (!pdata)
-   return -EINVAL;
-
hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
if (!hdata)
return -ENOMEM;

+   ret = drm_hdmi_dt_parse(hdata, dev->of_node);
+   if (ret)
+   return -EINVAL;
+
mutex_init(>hdmi_mutex);

platform_set_drvdata(pdev, _display);
@@ -2079,8 +2067,6 @@ static int hdmi_probe(struct platform_device *pdev)

drv_data = (struct hdmi_driver_data *)match->data;
hdata->type = drv_data->type;
-
-   hdata->hpd_gpio = pdata->hpd_gpio;
hdata->dev = dev;

ret = hdmi_resources_init(hdata);
-- 
1.7.9.5



[PATCHv3 0/5] drm: exynos: update/fixes to HDMI driver

2014-04-16 Thread Tomasz Stanislawski
Hi everyone,
This patchset adds 5 fixes/updates to EXYNOS DRM driver for
HDMI subsystem.

All comments are welcome.

Regards,
Tomasz Stanislawski

Changelog:

v3:
* remove usage of s5p_hdmi_platform_data
* return MODE_CLOCK_HIGH instead of MODE_CLOCK_BAD

v2:
* fix check with gpio_is_valid()
* use U32_MAX instead of ULONG_MAX to be 64-bit-friendly
* use hdmi_driver_data as hdmi's compatile data

v1:
* initial version

Tomasz Stanislawski (5):
  drm: exynos: hdmi: remove usage of struct s5p_hdmi_platform_data
  drm: exynos: hdmi: simplify extracting hpd-gpio from DT
  drm: exynos: mixer: fix using usleep() in atomic context
  drm: exynos: add compatibles for HDMI and Mixer chips and exynos4210
SoC
  drm: exynos: hdmi: add support for pixel clock limitation

 .../devicetree/bindings/video/exynos_hdmi.txt  |4 ++
 drivers/gpu/drm/exynos/exynos_hdmi.c   |   49 ++--
 drivers/gpu/drm/exynos/exynos_mixer.c  |5 +-
 3 files changed, 33 insertions(+), 25 deletions(-)

-- 
1.7.9.5



[PATCHv2 4/4] drm: exynos: hdmi: add support for pixel clock limitation

2014-04-15 Thread Tomasz Stanislawski
On 04/15/2014 03:42 PM, Rahul Sharma wrote:
> On 15 April 2014 18:41, Tomasz Stanislawski  
> wrote:
>> On 04/15/2014 11:42 AM, Rahul Sharma wrote:
>>> Hi Tomasz,
>>>
>>> On 15 April 2014 14:57, Tomasz Stanislawski  
>>> wrote:
>>>> Adds support for limitation of maximal pixel clock of HDMI
>>>> signal. This feature is needed on boards that contains
>>>> lines or bridges with frequency limitations.
>>>>
>>>> Signed-off-by: Tomasz Stanislawski 
[snip]

>>>> diff --git a/include/media/s5p_hdmi.h b/include/media/s5p_hdmi.h
>>>> index 181642b..7272d65 100644
>>>> --- a/include/media/s5p_hdmi.h
>>>> +++ b/include/media/s5p_hdmi.h
>>>> @@ -31,6 +31,7 @@ struct s5p_hdmi_platform_data {
>>>> int mhl_bus;
>>>> struct i2c_board_info *mhl_info;
>>>> int hpd_gpio;
>>>> +   u32 max_pixel_clock;
>>>>  };
>>>
>>> We have already removed Non DT support from the drm hdmi
>>> driver. IMO we should not be extending the pdata struct.
>>>
>>> Regards,
>>> Rahul Sharma
>>
>> Hi Rahul,
>>
>> This is not a non-DT patch. The s5p_hdmi_platform_data is
>> generated from DT itself. This structure is just
>> a parsed version of DT attributes.
>>
>> It may be a good idea to rename s5p_hdmi_platform_data
>> to exynos_hdmi_pdata and move it to exynos_hdmi_drm.c file
>> or parse DT directly in probe function.
>>
>> I can prepare a patch for that.
> 
> Else we can completely remove the dependency from
> s5p_hdmi_platform_data. We can directly assign to hdmi context
> variables. Later we can remove that struct itself from include/.
> What you say?

This structure cannot be removed from include yet because it is used by s5p-tv 
driver.
However its usage can be removed from both drivers.
I can prepare both.

> 
> Regards,
> Rahul Sharma
> 

Regards,
Tomasz Stanislawski

>>
>> Regards,
>> Tomasz Stanislawski
>>
>>
>>>
>>>>
>>>>  #endif /* S5P_HDMI_H */
>>>> --
>>>> 1.7.9.5
>>>>
>>>> ___
>>>> dri-devel mailing list
>>>> dri-devel at lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
> 



[PATCHv2 4/4] drm: exynos: hdmi: add support for pixel clock limitation

2014-04-15 Thread Tomasz Stanislawski
On 04/15/2014 11:42 AM, Rahul Sharma wrote:
> Hi Tomasz,
> 
> On 15 April 2014 14:57, Tomasz Stanislawski  
> wrote:
>> Adds support for limitation of maximal pixel clock of HDMI
>> signal. This feature is needed on boards that contains
>> lines or bridges with frequency limitations.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> ---
>>  .../devicetree/bindings/video/exynos_hdmi.txt  |4 
>>  drivers/gpu/drm/exynos/exynos_hdmi.c   |   12 
>>  include/media/s5p_hdmi.h   |1 +
>>  3 files changed, 17 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt 
>> b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> index f9187a2..8718f8d 100644
>> --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> @@ -28,6 +28,10 @@ Required properties:
>>  - ddc: phandle to the hdmi ddc node
>>  - phy: phandle to the hdmi phy node
>>
>> +Optional properties:
>> +- max-pixel-clock: used to limit the maximal pixel clock if a board has 
>> lines,
>> +   connectors or bridges not capable of carring higher frequencies
>> +
>>  Example:
>>
>> hdmi {
>> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
>> b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> index 2a18f4e..404f1b7 100644
>> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
>> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> @@ -195,6 +195,7 @@ struct hdmi_context {
>> struct hdmi_resources   res;
>>
>> int hpd_gpio;
>> +   u32 max_pixel_clock;
>>
>> enum hdmi_type  type;
>>  };
>> @@ -887,6 +888,9 @@ static int hdmi_mode_valid(struct drm_connector 
>> *connector,
>> if (ret)
>> return MODE_BAD;
>>
>> +   if (mode->clock * 1000 > hdata->max_pixel_clock)
>> +   return MODE_BAD;
>> +
>> ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
>> if (ret < 0)
>> return MODE_BAD;
>> @@ -2031,6 +2035,8 @@ static struct s5p_hdmi_platform_data 
>> *drm_hdmi_dt_parse_pdata
>> return NULL;
>> }
>>
>> +   of_property_read_u32(np, "max-pixel-clock", >max_pixel_clock);
>> +
>> return pd;
>>  }
>>
>> @@ -2067,6 +2073,11 @@ static int hdmi_probe(struct platform_device *pdev)
>> if (!pdata)
>> return -EINVAL;
>>
>> +   if (!pdata->max_pixel_clock) {
>> +   DRM_INFO("max-pixel-clock is zero, using INF\n");
>> +   pdata->max_pixel_clock = U32_MAX;
>> +   }
>> +
>> hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
>> if (!hdata)
>> return -ENOMEM;
>> @@ -2083,6 +2094,7 @@ static int hdmi_probe(struct platform_device *pdev)
>> hdata->type = drv_data->type;
>>
>> hdata->hpd_gpio = pdata->hpd_gpio;
>> +   hdata->max_pixel_clock = pdata->max_pixel_clock;
>> hdata->dev = dev;
>>
>> ret = hdmi_resources_init(hdata);
>> diff --git a/include/media/s5p_hdmi.h b/include/media/s5p_hdmi.h
>> index 181642b..7272d65 100644
>> --- a/include/media/s5p_hdmi.h
>> +++ b/include/media/s5p_hdmi.h
>> @@ -31,6 +31,7 @@ struct s5p_hdmi_platform_data {
>> int mhl_bus;
>>     struct i2c_board_info *mhl_info;
>> int hpd_gpio;
>> +   u32 max_pixel_clock;
>>  };
> 
> We have already removed Non DT support from the drm hdmi
> driver. IMO we should not be extending the pdata struct.
> 
> Regards,
> Rahul Sharma

Hi Rahul,

This is not a non-DT patch. The s5p_hdmi_platform_data is
generated from DT itself. This structure is just
a parsed version of DT attributes.

It may be a good idea to rename s5p_hdmi_platform_data
to exynos_hdmi_pdata and move it to exynos_hdmi_drm.c file
or parse DT directly in probe function.

I can prepare a patch for that.

Regards,
Tomasz Stanislawski


> 
>>
>>  #endif /* S5P_HDMI_H */
>> --
>> 1.7.9.5
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel



[PATCHv2 4/4] drm: exynos: hdmi: add support for pixel clock limitation

2014-04-15 Thread Tomasz Stanislawski
Adds support for limitation of maximal pixel clock of HDMI
signal. This feature is needed on boards that contains
lines or bridges with frequency limitations.

Signed-off-by: Tomasz Stanislawski 
---
 .../devicetree/bindings/video/exynos_hdmi.txt  |4 
 drivers/gpu/drm/exynos/exynos_hdmi.c   |   12 
 include/media/s5p_hdmi.h   |1 +
 3 files changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt 
b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
index f9187a2..8718f8d 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
@@ -28,6 +28,10 @@ Required properties:
 - ddc: phandle to the hdmi ddc node
 - phy: phandle to the hdmi phy node

+Optional properties:
+- max-pixel-clock: used to limit the maximal pixel clock if a board has lines,
+   connectors or bridges not capable of carring higher frequencies
+
 Example:

hdmi {
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 2a18f4e..404f1b7 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -195,6 +195,7 @@ struct hdmi_context {
struct hdmi_resources   res;

int hpd_gpio;
+   u32 max_pixel_clock;

enum hdmi_type  type;
 };
@@ -887,6 +888,9 @@ static int hdmi_mode_valid(struct drm_connector *connector,
if (ret)
return MODE_BAD;

+   if (mode->clock * 1000 > hdata->max_pixel_clock)
+   return MODE_BAD;
+
ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
if (ret < 0)
return MODE_BAD;
@@ -2031,6 +2035,8 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata
return NULL;
}

+   of_property_read_u32(np, "max-pixel-clock", >max_pixel_clock);
+
return pd;
 }

@@ -2067,6 +2073,11 @@ static int hdmi_probe(struct platform_device *pdev)
if (!pdata)
return -EINVAL;

+   if (!pdata->max_pixel_clock) {
+   DRM_INFO("max-pixel-clock is zero, using INF\n");
+   pdata->max_pixel_clock = U32_MAX;
+   }
+
hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
if (!hdata)
return -ENOMEM;
@@ -2083,6 +2094,7 @@ static int hdmi_probe(struct platform_device *pdev)
hdata->type = drv_data->type;

hdata->hpd_gpio = pdata->hpd_gpio;
+   hdata->max_pixel_clock = pdata->max_pixel_clock;
hdata->dev = dev;

ret = hdmi_resources_init(hdata);
diff --git a/include/media/s5p_hdmi.h b/include/media/s5p_hdmi.h
index 181642b..7272d65 100644
--- a/include/media/s5p_hdmi.h
+++ b/include/media/s5p_hdmi.h
@@ -31,6 +31,7 @@ struct s5p_hdmi_platform_data {
int mhl_bus;
struct i2c_board_info *mhl_info;
int hpd_gpio;
+   u32 max_pixel_clock;
 };

 #endif /* S5P_HDMI_H */
-- 
1.7.9.5



[PATCHv2 3/4] drm: exynos: add compatibles for HDMI and Mixer chips and exynos4210 SoC

2014-04-15 Thread Tomasz Stanislawski
This patch add proper compatibles for Mixer and HDMI chip
available on exynos4210 SoCs.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c  |7 +++
 drivers/gpu/drm/exynos/exynos_mixer.c |3 +++
 2 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 47c6e85..2a18f4e 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -204,6 +204,10 @@ struct hdmiphy_config {
u8 conf[32];
 };

+struct hdmi_driver_data exynos4210_hdmi_driver_data = {
+   .type   = HDMI_TYPE13,
+};
+
 struct hdmi_driver_data exynos4212_hdmi_driver_data = {
.type   = HDMI_TYPE14,
 };
@@ -2032,6 +2036,9 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata

 static struct of_device_id hdmi_match_types[] = {
{
+   .compatible = "samsung,exynos4210-hdmi",
+   .data = _hdmi_driver_data,
+   }, {
.compatible = "samsung,exynos5-hdmi",
.data = _hdmi_driver_data,
}, {
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index e3306c8..fd8a9a0 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1187,6 +1187,9 @@ static struct platform_device_id mixer_driver_types[] = {

 static struct of_device_id mixer_match_types[] = {
{
+   .compatible = "samsung,exynos4210-mixer",
+   .data   = _mxr_drv_data,
+   }, {
.compatible = "samsung,exynos5-mixer",
.data   = _mxr_drv_data,
}, {
-- 
1.7.9.5



[PATCHv2 2/4] drm: exynos: mixer: fix using usleep() in atomic context

2014-04-15 Thread Tomasz Stanislawski
This patch fixes calling usleep_range() after taking reg_slock
using spin_lock_irqsave(). The mdelay() is used instead.
Waiting in atomic context is not the best idea in general.
Hopefully, waiting occurs only when Video Processor fails
to reset correctly.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index ce28881..e3306c8 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -615,7 +615,7 @@ static void vp_win_reset(struct mixer_context *ctx)
/* waiting until VP_SRESET_PROCESSING is 0 */
if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
break;
-   usleep_range(1, 12000);
+   mdelay(10);
}
WARN(tries == 0, "failed to reset Video Processor\n");
 }
-- 
1.7.9.5



[PATCHv2 1/4] drm: exynos: hdmi: simplify extracting hpd-gpio from DT

2014-04-15 Thread Tomasz Stanislawski
This patch eliminates redundant checks while retrieving HPD gpio from DT during
HDMI's probe().

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9a6d652..47c6e85 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2016,23 +2016,18 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata
 {
struct device_node *np = dev->of_node;
struct s5p_hdmi_platform_data *pd;
-   u32 value;

pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd)
-   goto err_data;
+   return NULL;

-   if (!of_find_property(np, "hpd-gpio", )) {
+   pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
+   if (!gpio_is_valid(pd->hpd_gpio)) {
DRM_ERROR("no hpd gpio property found\n");
-   goto err_data;
+   return NULL;
}

-   pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
-
return pd;
-
-err_data:
-   return NULL;
 }

 static struct of_device_id hdmi_match_types[] = {
-- 
1.7.9.5



[PATCHv2 0/4] drm: exynos: update/fixes to HDMI driver

2014-04-15 Thread Tomasz Stanislawski
Hi everyone,
This patchset adds 4 fixes/updates to EXYNOS DRM driver for
HDMI subsystem.

All comments are welcome.

Regards,
Tomasz Stanislawski

Changelog:

v2:
* fix check with gpio_is_valid()
* use U32_MAX instead of ULONG_MAX to be 64-bit-friendly
* use hdmi_driver_data as hdmi's compatile data

v1:
* initial version

Tomasz Stanislawski (4):
  drm: exynos: hdmi: simplify extracting hpd-gpio from DT
  drm: exynos: mixer: fix using usleep() in atomic context
  drm: exynos: add compatibles for HDMI and Mixer chips and exynos4210
SoC
  drm: exynos: hdmi: add support for pixel clock limitation

 .../devicetree/bindings/video/exynos_hdmi.txt  |4 +++
 drivers/gpu/drm/exynos/exynos_hdmi.c   |   30 ++--
 drivers/gpu/drm/exynos/exynos_mixer.c  |5 +++-
 include/media/s5p_hdmi.h   |1 +
 4 files changed, 31 insertions(+), 9 deletions(-)

-- 
1.7.9.5



[PATCH 1/4] drm: exynos: hdmi: simplify extracting hpd-gpio from DT

2014-04-14 Thread Tomasz Stanislawski
On 04/14/2014 05:00 PM, Tomasz Stanislawski wrote:
> This patch eliminates redundant checks while retrieving HPD gpio from DT 
> during
> HDMI's probe().
> 
> Signed-off-by: Tomasz Stanislawski 
> ---
>  drivers/gpu/drm/exynos/exynos_hdmi.c |   13 -
>  1 file changed, 4 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
> b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index 9a6d652..d2d6e2e 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -2016,23 +2016,18 @@ static struct s5p_hdmi_platform_data 
> *drm_hdmi_dt_parse_pdata
>  {
>   struct device_node *np = dev->of_node;
>   struct s5p_hdmi_platform_data *pd;
> - u32 value;
>  
>   pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
>   if (!pd)
> - goto err_data;
> + return NULL;
>  
> - if (!of_find_property(np, "hpd-gpio", )) {
> + pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
> + if (gpio_is_valid(pd->hpd_gpio)) {

Sorry. Should be !gpio_is_valid().

>   DRM_ERROR("no hpd gpio property found\n");
> - goto err_data;
> + return NULL;
>   }
>  
> - pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
> -
>   return pd;
> -
> -err_data:
> - return NULL;
>  }
>  
>  static struct of_device_id hdmi_match_types[] = {
> 



[PATCH 4/4] drm: exynos: hdmi: add support for pixel clock limitation

2014-04-14 Thread Tomasz Stanislawski
Adds support for limitation of maximal pixel clock of HDMI
signal. This feature is needed on boards that contains
lines or bridges with frequency limitations.

Signed-off-by: Tomasz Stanislawski 
---
 .../devicetree/bindings/video/exynos_hdmi.txt  |4 
 drivers/gpu/drm/exynos/exynos_hdmi.c   |   12 
 include/media/s5p_hdmi.h   |1 +
 3 files changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt 
b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
index f9187a2..8718f8d 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
@@ -28,6 +28,10 @@ Required properties:
 - ddc: phandle to the hdmi ddc node
 - phy: phandle to the hdmi phy node

+Optional properties:
+- max-pixel-clock: used to limit the maximal pixel clock if a board has lines,
+   connectors or bridges not capable of carring higher frequencies
+
 Example:

hdmi {
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 6fa63ea..ca313b3 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -195,6 +195,7 @@ struct hdmi_context {
struct hdmi_resources   res;

int hpd_gpio;
+   u32 max_pixel_clock;

enum hdmi_type  type;
 };
@@ -883,6 +884,9 @@ static int hdmi_mode_valid(struct drm_connector *connector,
if (ret)
return MODE_BAD;

+   if (mode->clock * 1000 > hdata->max_pixel_clock)
+   return MODE_BAD;
+
ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
if (ret < 0)
return MODE_BAD;
@@ -2027,6 +2031,8 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata
return NULL;
}

+   of_property_read_u32(np, "max-pixel-clock", >max_pixel_clock);
+
return pd;
 }

@@ -2063,6 +2069,11 @@ static int hdmi_probe(struct platform_device *pdev)
if (!pdata)
return -EINVAL;

+   if (!pdata->max_pixel_clock) {
+   DRM_INFO("max-pixel-clock is zero, using INF\n");
+   pdata->max_pixel_clock = ULONG_MAX;
+   }
+
hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
if (!hdata)
return -ENOMEM;
@@ -2079,6 +2090,7 @@ static int hdmi_probe(struct platform_device *pdev)
hdata->type = drv_data->type;

hdata->hpd_gpio = pdata->hpd_gpio;
+   hdata->max_pixel_clock = pdata->max_pixel_clock;
hdata->dev = dev;

ret = hdmi_resources_init(hdata);
diff --git a/include/media/s5p_hdmi.h b/include/media/s5p_hdmi.h
index 181642b..7272d65 100644
--- a/include/media/s5p_hdmi.h
+++ b/include/media/s5p_hdmi.h
@@ -31,6 +31,7 @@ struct s5p_hdmi_platform_data {
int mhl_bus;
struct i2c_board_info *mhl_info;
int hpd_gpio;
+   u32 max_pixel_clock;
 };

 #endif /* S5P_HDMI_H */
-- 
1.7.9.5



[PATCH 3/4] drm: exynos: add compatibles for HDMI and Mixer chips and exynos4210 SoC

2014-04-14 Thread Tomasz Stanislawski
This patch add proper compatibles for Mixer and HDMI chip
available on exynos4210 SoCs.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c  |3 +++
 drivers/gpu/drm/exynos/exynos_mixer.c |3 +++
 2 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index d2d6e2e..6fa63ea 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2032,6 +2032,9 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata

 static struct of_device_id hdmi_match_types[] = {
{
+   .compatible = "samsung,exynos4210-hdmi",
+   .data   = (void *)HDMI_TYPE13,
+   }, {
.compatible = "samsung,exynos5-hdmi",
.data = _hdmi_driver_data,
}, {
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index e3306c8..fd8a9a0 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1187,6 +1187,9 @@ static struct platform_device_id mixer_driver_types[] = {

 static struct of_device_id mixer_match_types[] = {
{
+   .compatible = "samsung,exynos4210-mixer",
+   .data   = _mxr_drv_data,
+   }, {
.compatible = "samsung,exynos5-mixer",
.data   = _mxr_drv_data,
}, {
-- 
1.7.9.5



[PATCH 2/4] drm: exynos: mixer: fix using usleep() in atomic context

2014-04-14 Thread Tomasz Stanislawski
This patch fixes calling usleep_range() after taking reg_slock
using spin_lock_irqsave(). The mdelay() is used instead.
Waiting in atomic context is not the best idea in general.
Hopefully, waiting occurs only when Video Processor fails
to reset correctly.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index ce28881..e3306c8 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -615,7 +615,7 @@ static void vp_win_reset(struct mixer_context *ctx)
/* waiting until VP_SRESET_PROCESSING is 0 */
if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
break;
-   usleep_range(1, 12000);
+   mdelay(10);
}
WARN(tries == 0, "failed to reset Video Processor\n");
 }
-- 
1.7.9.5



[PATCH 1/4] drm: exynos: hdmi: simplify extracting hpd-gpio from DT

2014-04-14 Thread Tomasz Stanislawski
This patch eliminates redundant checks while retrieving HPD gpio from DT during
HDMI's probe().

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9a6d652..d2d6e2e 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2016,23 +2016,18 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata
 {
struct device_node *np = dev->of_node;
struct s5p_hdmi_platform_data *pd;
-   u32 value;

pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd)
-   goto err_data;
+   return NULL;

-   if (!of_find_property(np, "hpd-gpio", )) {
+   pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
+   if (gpio_is_valid(pd->hpd_gpio)) {
DRM_ERROR("no hpd gpio property found\n");
-   goto err_data;
+   return NULL;
}

-   pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
-
return pd;
-
-err_data:
-   return NULL;
 }

 static struct of_device_id hdmi_match_types[] = {
-- 
1.7.9.5



[PATCH 0/4] drm: exynos: update/fixes to HDMI driver

2014-04-14 Thread Tomasz Stanislawski
Hi everyone,
This patchset adds 4 fixes/updates to EXYNOS DRM driver for
HDMI subsystem.

All comments are welcome.

Regards,
Tomasz Stanislawski

Tomasz Stanislawski (4):
  drm: exynos: hdmi: simplify extracting hpd-gpio from DT
  drm: exynos: mixer: fix using usleep() in atomic context
  drm: exynos: add compatibles for HDMI and Mixer chips and exynos4210
SoC
  drm: exynos: hdmi: add support for pixel clock limitation

 .../devicetree/bindings/video/exynos_hdmi.txt  |4 +++
 drivers/gpu/drm/exynos/exynos_hdmi.c   |   26 ++--
 drivers/gpu/drm/exynos/exynos_mixer.c  |5 +++-
 include/media/s5p_hdmi.h   |1 +
 4 files changed, 27 insertions(+), 9 deletions(-)

-- 
1.7.9.5



[PATCH] drm: exynos: hdmi: simplify extracting hpd-gpio from DT

2014-04-14 Thread Tomasz Stanislawski
This patch eliminates redundant checks while retrieving HPD gpio from DT during
HDMI's probe().

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index e1a2e88..300c2af 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2011,23 +2011,18 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata
 {
struct device_node *np = dev->of_node;
struct s5p_hdmi_platform_data *pd;
-   u32 value;

pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd)
-   goto err_data;
+   return NULL;

-   if (!of_find_property(np, "hpd-gpio", )) {
+   pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, NULL);
+   if (pd->hpd_gpio < 0) {
DRM_ERROR("no hpd gpio property found\n");
-   goto err_data;
+   return NULL;
}

-   pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
-
return pd;
-
-err_data:
-   return NULL;
 }

 static struct of_device_id hdmi_match_types[] = {



[PATCH 2/2] arm: dts: trats2: add SiI9234 node

2014-04-11 Thread Tomasz Stanislawski
This patch adds configuration of SiI9234 bridge to Trats2 board.

Signed-off-by: Tomasz Stanislawski 
---
 arch/arm/boot/dts/exynos4412-trats2.dts |   43 +++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts 
b/arch/arm/boot/dts/exynos4412-trats2.dts
index 9583563d..65fd1d4 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -680,4 +680,47 @@
pulldown-ohm = <10>; /* 100K */
io-channels = < 2>;  /* Battery temperature */
};
+
+   vsil: voltage-regulator-vsil {
+   compatible = "regulator-fixed";
+   regulator-name = "HDMI_5V";
+   regulator-min-microvolt = <500>;
+   regulator-max-microvolt = <500>;
+   gpio = < 4 0>;
+   enable-active-high;
+   vin-supply = <_reg>;
+   };
+
+   i2c-mhl {
+   compatible = "i2c-gpio";
+   gpios = < 4 0  6 0>;
+   i2c-gpio,delay-us = <100>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   pinctrl-0 = <_mhl_bus>;
+   pinctrl-names = "default";
+   status = "okay";
+
+   sii9234: sii9234 at 39 {
+   compatible = "sil,sii9234";
+   vcc-supply = <>;
+   gpio-reset = < 4 0>;
+   gpio-int = < 5 0>;
+   reg = <0x39>;
+   };
+   };
+};
+
+_0 {
+   mhl_int: mhl-int {
+   samsung,pins = "gpf3-5";
+   samsung,pin-pud = <0>;
+   };
+   i2c_mhl_bus: i2c-mhl-bus {
+   samsung,pins = "gpf0-4", "gpf0-6";
+   samsung,pin-function = <2>;
+   samsung,pin-pud = <1>;
+   samsung,pin-drv = <0>;
+   };
 };
-- 
1.7.9.5



[PATCH 1/2] misc: add sii9234 driver

2014-04-11 Thread Tomasz Stanislawski
Add driver for HDMI bridge using MHL connection.
Contains refactored code for MHL driver developed by:

Adam Hampson 
Erik Gilling 
Shankar Bandal 
Dharam Kumar 

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 Documentation/devicetree/bindings/sii9234.txt |   22 +
 drivers/misc/Kconfig  |8 +
 drivers/misc/Makefile |1 +
 drivers/misc/sii9234.c| 1081 +
 4 files changed, 1112 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sii9234.txt
 create mode 100644 drivers/misc/sii9234.c

diff --git a/Documentation/devicetree/bindings/sii9234.txt 
b/Documentation/devicetree/bindings/sii9234.txt
new file mode 100644
index 000..4431139
--- /dev/null
+++ b/Documentation/devicetree/bindings/sii9234.txt
@@ -0,0 +1,22 @@
+SiI9234 Mobile HD Link Transmitter
+
+Required properties:
+- compatible : "sil,sii9234".
+- reg : I2C address for TPI interface, use 0x39
+- vcc-supply : regulator that supplies the chip
+- gpio-reset : GPIO connected to RESET_N pin
+- gpio-int : GPIO connected to INT pin
+
+Optional properties:
+- extcon : phandle to extcon that wakes up the chip
+
+Additional compatible properties are also allowed.
+
+Example:
+   sii9234 at 39 {
+   compatible = "sil,sii9234";
+   reg = <0x39>;
+   vcc-supply = <>;
+   gpio-reset = < 4 0>;
+   gpio-int = < 5 0>;
+   };
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1cb7408..3b7f266 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -515,6 +515,14 @@ config SRAM
  the genalloc API. It is supposed to be used for small on-chip SRAM
  areas found on many SoCs.

+config SII9234
+   tristate "Silicon Image SII9234 Driver"
+   depends on I2C
+   help
+ Say Y here if you want support for the MHL interface.
+ It is an I2C driver, that detects connection of MHL bridge
+ and starts encapsulation of HDMI signal.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7eb4b69..145a47a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_SRAM)+= sram.o
 obj-y  += mic/
 obj-$(CONFIG_GENWQE)   += genwqe/
 obj-$(CONFIG_ECHO) += echo/
+obj-$(CONFIG_SII9234)  += sii9234.o
diff --git a/drivers/misc/sii9234.c b/drivers/misc/sii9234.c
new file mode 100644
index 000..60b7c66
--- /dev/null
+++ b/drivers/misc/sii9234.c
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics
+ *
+ * Author: Tomasz Stanislawski 
+ *
+ * Based on sii9234 driver created by:
+ *Adam Hampson 
+ *Erik Gilling 
+ *Shankar Bandal 
+ *Dharam Kumar 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* MHL Tx registers and bits */
+#define MHL_TX_SRST 0x05
+#define MHL_TX_SYSSTAT_REG  0x09
+#define RSEN_STATUS (1<<2)
+#define MHL_TX_INTR1_REG0x71
+#define HPD_CHANGE_INT  (1<<6)
+#define RSEN_CHANGE_INT (1<<5)
+#define MHL_TX_INTR4_REG0x74
+#define RGND_READY_INT  (1<<6)
+#define VBUS_LOW_INT(1<<5)
+#define CBUS_LKOUT_INT  (1<<4)
+#define MHL_DISC_FAIL_INT   (1<<3)
+#define MHL_EST_INT (1<<2)
+#define MHL_TX_INTR1_ENABLE_REG 0x75
+#define HPD_CHANGE_INT_MASK (1<<6)
+#define RSEN_CHANGE_INT_MASK(1<<5)
+#define MHL_TX_INTR4_ENABLE_REG 0x78
+#define RGND_READY_MASK (1<<6)
+#define CBUS_LKOUT_MASK (1<<4)
+#define MHL_DISC_FAIL_MASK  (1<<3)
+#define MHL_EST_MASK(1<<2)
+#define MHL_TX_INT_CTRL_REG 0x79
+#define MHL_TX_

[PATCH 0/2] Add support for sii9234 chip

2014-04-11 Thread Tomasz Stanislawski
Hi everyone,
This patchset adds support for sii9234 HD Mobile Link Bridge.  The chip is used
to convert HDMI signal into MHL.  The driver enables HDMI output on Trats and
Trats2 boards.

The code is based on the driver [1] developed by:
   Adam Hampson 
   Erik Gilling 
with additional contributions from:
   Shankar Bandal 
   Dharam Kumar 

The drivers architecture was greatly simplified and transformed into a form
accepted (hopefully) by opensource community.  The main differences from
original code are:
* using single I2C client instead of 4 subclients
* remove all logic non-related to establishing HDMI link
* simplify error handling
* rewrite state machine in interrupt handler
* wakeup and discovery triggered by an extcon event
* integrate with Device Tree

For now, the driver is added to drivers/misc/ directory because it has neigher
userspace nor kernel interface.  The chip is capable of receiving and
processing CEC events, so the driver may export an input device in /dev/ in the
future.  However CEC could be also handled by HDMI driver.

I kindly ask for suggestions about the best location for this driver.

Both the chip and the driver are quite autonomic. The chip works as 'invisible
proxy' for HDMI signal, so there is no need to integrate it with HDMI drivers
by helper-subsystems like v4l2_subdev or drm_bridge.  If the driver is merged
then the driver from drivers/media/platform/s5p-tv/sii9234_drv.c could be safely
removed.

All comments are welcome.

Regards,
Tomasz Stanislawski


References:
[1] 
https://github.com/junpei0824/SC02C-linux/tree/master-jelly-cm-aokp/drivers/media/video/mhl


Tomasz Stanislawski (2):
  misc: add sii9234 driver
  arm: dts: trats2: add SiI9234 node

 Documentation/devicetree/bindings/sii9234.txt |   22 +
 arch/arm/boot/dts/exynos4412-trats2.dts   |   43 +
 drivers/misc/Kconfig  |8 +
 drivers/misc/Makefile |1 +
 drivers/misc/sii9234.c| 1081 +
 5 files changed, 1155 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sii9234.txt
 create mode 100644 drivers/misc/sii9234.c

-- 
1.7.9.5



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

2014-04-09 Thread Tomasz Stanislawski
Hi Rahul,

On 04/09/2014 11:12 AM, Rahul Sharma wrote:
> Hi Tomasz,
> 
> On 9 April 2014 14:07, Andrzej Hajda  wrote:
>> Hi Tomasz,
>>
>> On 04/08/2014 04:37 PM, Tomasz Stanislawski wrote:
>>> Add exynos-simple-phy driver to support a single register
>>> PHY interfaces present on Exynos4 SoC.
>>>
>>> Signed-off-by: Tomasz Stanislawski 

[snip]

>>> +
>>> + regs = devm_ioremap(dev, res->start, res->end - res->start);
>>> + if (!regs) {
>>> + dev_err(dev, "failed to ioremap registers\n");
>>> + return -EFAULT;
>>> + }
>>
>> Why not devm_ioremap_resource? If not, resource_size function calculates
>> length of resource correctly.
>>
>> Anyway I like the idea of implementing multiple phys in one driver.
>> The only drawback I see is that some phys will be created even there are
>> no consumers for them. To avoid such situation you can try to use
>> lazy approach - create phy only if there is request for it,
>> exynos_phy_xlate callback should allow this.
>>
>> Regards
>> Andrzej
>>
> 
> Idea looks good. How about keeping compatible which is independent
> of SoC, something like "samsung,exynos-simple-phy" and provide Reg
> and Bit through phy provider node. This way we can avoid SoC specific
> hardcoding in phy driver and don't need to look into dt bindings for
> each new SoC.

A very nice idea BUT there is a very strong pressure from DT guys
to avoid adding any bit fields/offsets/masks in DT nodes.

Hopefully, as long as driver name starts with "exynos-" prefix
one can hide SoCs specific tricks deep inside driver code.

The idea behind this driver was not to create a generic phy for 1-bit
devices but rather to hide SoC-specific issues from client drivers
like DRM-HDMI.

> 
> We can use syscon interface to access PMU bits like USB phy.
> PMU is already registered as system controller
> 

Ok. I will try to use it in PATCHv3.

> Regards,
> Rahul Sharma.
> 

Regards,
Tomasz Stanislawski




[PATCHv2 2/3] drm: exynos: hdmi: use hdmiphy as PHY

2014-04-09 Thread Tomasz Stanislawski
Hi Andrzej,
This issue could be solved by exporting a regmap from PMU driver
or Exynos clock provider for the usage by exynos-simple-phy.
The operations on PHYs from exynos-simple-phy provider would
be chained to PMU driver and protected by a spinlock in the regmap.

Luckily, the divider is not used as far as I know.

Regards,
Tomasz Stanislawski

On 04/09/2014 12:30 PM, Andrzej Hajda wrote:
> Hi Tomasz,
> 
> On 04/08/2014 04:37 PM, Tomasz Stanislawski wrote:
>> The HDMIPHY (physical interface) is controlled by a single
>> bit in a power controller's regiter. It was implemented
>> as clock. It was a simple but effective hack.
> 
> This power controller register has also bits to control HDMI clock
> divider ratio. I guess current drivers do not change it, but how do you
> want to implement access to it if some HDMI driver in the future will
> need to change ratio. I guess in case of clk it would be easier.
> 
> Regards
> Andrzej
> 
> 



[PATCHv2 3/3] s5p-tv: hdmi: use hdmiphy as PHY

2014-04-08 Thread Tomasz Stanislawski
The HDMIPHY (physical interface) is controlled by a single
bit in a power controller's regiter. It was implemented
as clock. It was a simple but effective hack.

This patch makes S5P-HDMI driver to control HDMIPHY via PHY interface.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/media/platform/s5p-tv/hdmi_drv.c |   11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/s5p-tv/hdmi_drv.c 
b/drivers/media/platform/s5p-tv/hdmi_drv.c
index 534722c..8013e52 100644
--- a/drivers/media/platform/s5p-tv/hdmi_drv.c
+++ b/drivers/media/platform/s5p-tv/hdmi_drv.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
@@ -66,7 +67,7 @@ struct hdmi_resources {
struct clk *sclk_hdmi;
struct clk *sclk_pixel;
struct clk *sclk_hdmiphy;
-   struct clk *hdmiphy;
+   struct phy *hdmiphy;
struct regulator_bulk_data *regul_bulk;
int regul_count;
 };
@@ -586,7 +587,7 @@ static int hdmi_resource_poweron(struct hdmi_resources *res)
if (ret < 0)
return ret;
/* power-on hdmi physical interface */
-   clk_enable(res->hdmiphy);
+   phy_power_on(res->hdmiphy);
/* use VPP as parent clock; HDMIPHY is not working yet */
clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
/* turn clocks on */
@@ -600,7 +601,7 @@ static void hdmi_resource_poweroff(struct hdmi_resources 
*res)
/* turn clocks off */
clk_disable(res->sclk_hdmi);
/* power-off hdmiphy */
-   clk_disable(res->hdmiphy);
+   phy_power_off(res->hdmiphy);
/* turn HDMI power off */
regulator_bulk_disable(res->regul_count, res->regul_bulk);
 }
@@ -784,7 +785,7 @@ static void hdmi_resources_cleanup(struct hdmi_device *hdev)
/* kfree is NULL-safe */
kfree(res->regul_bulk);
if (!IS_ERR(res->hdmiphy))
-   clk_put(res->hdmiphy);
+   phy_put(res->hdmiphy);
if (!IS_ERR(res->sclk_hdmiphy))
clk_put(res->sclk_hdmiphy);
if (!IS_ERR(res->sclk_pixel))
@@ -835,7 +836,7 @@ static int hdmi_resources_init(struct hdmi_device *hdev)
dev_err(dev, "failed to get clock 'sclk_hdmiphy'\n");
goto fail;
}
-   res->hdmiphy = clk_get(dev, "hdmiphy");
+   res->hdmiphy = phy_get(dev, "hdmiphy");
if (IS_ERR(res->hdmiphy)) {
dev_err(dev, "failed to get clock 'hdmiphy'\n");
goto fail;
-- 
1.7.9.5



[PATCHv2 2/3] drm: exynos: hdmi: use hdmiphy as PHY

2014-04-08 Thread Tomasz Stanislawski
The HDMIPHY (physical interface) is controlled by a single
bit in a power controller's regiter. It was implemented
as clock. It was a simple but effective hack.

This patch makes HDMI driver to control HDMIPHY via PHY interface.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9a6d652..ef1cdd0 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 

@@ -74,8 +75,8 @@ struct hdmi_resources {
struct clk  *sclk_hdmi;
struct clk  *sclk_pixel;
struct clk  *sclk_hdmiphy;
-   struct clk  *hdmiphy;
struct clk  *mout_hdmi;
+   struct phy  *hdmiphy;
struct regulator_bulk_data  *regul_bulk;
int regul_count;
 };
@@ -1854,7 +1855,7 @@ static void hdmi_poweron(struct exynos_drm_display 
*display)
if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
DRM_DEBUG_KMS("failed to enable regulator bulk\n");

-   clk_prepare_enable(res->hdmiphy);
+   phy_power_on(res->hdmiphy);
clk_prepare_enable(res->hdmi);
clk_prepare_enable(res->sclk_hdmi);

@@ -1881,7 +1882,7 @@ static void hdmi_poweroff(struct exynos_drm_display 
*display)

clk_disable_unprepare(res->sclk_hdmi);
clk_disable_unprepare(res->hdmi);
-   clk_disable_unprepare(res->hdmiphy);
+   phy_power_off(res->hdmiphy);
regulator_bulk_disable(res->regul_count, res->regul_bulk);

pm_runtime_put_sync(hdata->dev);
@@ -1977,9 +1978,9 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
goto fail;
}
-   res->hdmiphy = devm_clk_get(dev, "hdmiphy");
+   res->hdmiphy = devm_phy_get(dev, "hdmiphy");
if (IS_ERR(res->hdmiphy)) {
-   DRM_ERROR("failed to get clock 'hdmiphy'\n");
+   DRM_ERROR("failed to get phy 'hdmiphy'\n");
goto fail;
}
res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
-- 
1.7.9.5



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

2014-04-08 Thread Tomasz Stanislawski
Add exynos-simple-phy driver to support a single register
PHY interfaces present on Exynos4 SoC.

Signed-off-by: Tomasz Stanislawski 
---
 .../devicetree/bindings/phy/samsung-phy.txt|   24 +++
 drivers/phy/Kconfig|5 +
 drivers/phy/Makefile   |1 +
 drivers/phy/exynos-simple-phy.c|  154 
 4 files changed, 184 insertions(+)
 create mode 100644 drivers/phy/exynos-simple-phy.c

diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt 
b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index b422e38..f97c4c3 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -114,3 +114,27 @@ Example:
compatible = "samsung,exynos-sataphy-i2c";
reg = <0x38>;
};
+
+Samsung S5P/EXYNOS SoC series SIMPLE PHY
+-
+
+Required properties:
+- compatible : should be one of the listed compatibles:
+   - "samsung,exynos4210-simple-phy"
+   - "samsung,exynos4412-simple-phy"
+- reg : offset and length of the register set;
+- #phy-cells : from the generic phy bindings, must be 1;
+
+For "samsung,exynos4210-simple-phy" compatible PHYs the second cell in
+the PHY specifier identifies the PHY and its meaning is as follows:
+  0 - HDMI PHY,
+  1 - DAC PHY,
+  2 - ADC PHY,
+  3 - PCIE PHY.
+  4 - SATA PHY.
+
+For "samsung,exynos4412-simple-phy" compatible PHYs the second cell in
+the PHY specifier identifies the PHY and its meaning is as follows:
+  0 - HDMI PHY,
+  1 - ADC PHY,
+
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 3bb05f1..65ab783 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -166,4 +166,9 @@ config PHY_XGENE
help
  This option enables support for APM X-Gene SoC multi-purpose PHY.

+config EXYNOS_SIMPLE_PHY
+   tristate "Exynos Simple PHY driver"
+   help
+ Support for 1-bit PHY controllers on SoCs from Exynos family.
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 2faf78e..88c5b60 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
 obj-$(CONFIG_PHY_EXYNOS4X12_USB2)  += phy-exynos4x12-usb2.o
 obj-$(CONFIG_PHY_EXYNOS5250_USB2)  += phy-exynos5250-usb2.o
 obj-$(CONFIG_PHY_XGENE)+= phy-xgene.o
+obj-$(CONFIG_EXYNOS_SIMPLE_PHY)+= exynos-simple-phy.o
diff --git a/drivers/phy/exynos-simple-phy.c b/drivers/phy/exynos-simple-phy.c
new file mode 100644
index 000..57ad338
--- /dev/null
+++ b/drivers/phy/exynos-simple-phy.c
@@ -0,0 +1,154 @@
+/*
+ * Exynos Simple PHY driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Tomasz Stanislawski 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define EXYNOS_PHY_ENABLE  (1 << 0)
+
+static int exynos_phy_power_on(struct phy *phy)
+{
+   void __iomem *reg = phy_get_drvdata(phy);
+   u32 val;
+
+   val = readl(reg);
+   val |= EXYNOS_PHY_ENABLE;
+   writel(val, reg);
+
+   return 0;
+}
+
+static int exynos_phy_power_off(struct phy *phy)
+{
+   void __iomem *reg = phy_get_drvdata(phy);
+   u32 val;
+
+   val = readl(reg);
+   val &= ~EXYNOS_PHY_ENABLE;
+   writel(val, reg);
+
+   return 0;
+}
+
+static struct phy_ops exynos_phy_ops = {
+   .power_on   = exynos_phy_power_on,
+   .power_off  = exynos_phy_power_off,
+   .owner  = THIS_MODULE,
+};
+
+static const u32 exynos4210_offsets[] = {
+   0x0700, /* HDMI_PHY */
+   0x070C, /* DAC_PHY */
+   0x0718, /* ADC_PHY */
+   0x071C, /* PCIE_PHY */
+   0x0720, /* SATA_PHY */
+   ~0, /* end mark */
+};
+
+static const u32 exynos4412_offsets[] = {
+   0x0700, /* HDMI_PHY */
+   0x0718, /* ADC_PHY */
+   ~0, /* end mark */
+};
+
+static const struct of_device_id exynos_phy_of_match[] = {
+   { .compatible = "samsung,exynos4210-simple-phy",
+ .data = exynos4210_offsets},
+   { .compatible = "samsung,exynos4412-simple-phy",
+ .data = exynos4412_offsets},
+   { },
+};
+MODULE_DEVICE_TABLE(of, exynos_phy_of_match);
+
+static struct phy *exynos_phy_xlate(struct device *dev,
+   struct of_phandle_args *args)
+{
+   struct phy **phys = dev_get_drvdata(dev);
+   int index = args->args[0];
+   int i;
+
+   /* verify if index is valid */
+   for (i = 0; i <= index; ++i)
+   if (!ph

[PATCHv2 0/3] phy: Add exynos-simple-phy driver

2014-04-08 Thread Tomasz Stanislawski
Hello everyone,

The Samsung SoCs from Exynos family are enhanced with a bunch of devices that
provide functionality of a physical layer for interfaces like USB, HDMI, SATA,
etc. They are controlled by a simple interface, often a single bit that enables
and/or resets the physical layer.

An IP driver should to control such a controller in an abstract manner.
Therefore, such 'enablers' were implemented as clocks in older versions of
Linux kernel.  With the dawn of PHY subsystems, PHYs become a natural way of
exporting the 'enabler' functionality to drivers.  However, there is an
unexpected consequence. Some of those 1-bit PHYs were implemented as separate
drivers.  This means that one has to create a struct device, struct phy, its
phy provider and 100-150 lines of driver code to basically set one bit.

The DP phy driver is a good example:
https://lkml.org/lkml/2013/7/18/53

And simple-phy RFC (shares only driver code but not other resources):
https://lkml.org/lkml/2013/10/21/313

To avoid waste of resources I propose to create all such 1-bit phys from Exynos
SoC using a single device, driver and phy provider.

This patchset contains a proposed solution.

All comment are welcome.

Hopefully in future the functionality introduced by this patch may be merged
into a larger Power Management Unit (PMU) gluer driver.  On Samsusng SoC , the
PMU part contains a number of register barely linked to power management (like
clock gating, clock dividers, CPU resetting, etc.).  It may be tempting to
create a hybrid driver that export clocks/phys/etc that are controlled by PMU
unit.

Alternative solutions might be:
* exporting a regmap to the IP driver and allow the driver to control the PHY 
layer
  like in the patch:
  http://thread.gmane.org/gmane.linux.kernel.samsung-soc/28617/focus=28648

* create a dedicated power domain for hdmiphy

Regards,
Tomasz Stanislawski

Changelog:
v2:
* rename to exynos-simple-phy
* fix usage of devm_ioremap()
* add documentation for DT bindings
* add patches to client drivers

v1: initial version

Tomasz Stanislawski (3):
  phy: Add exynos-simple-phy driver
  drm: exynos: hdmi: use hdmiphy as PHY
  s5p-tv: hdmi: use hdmiphy as PHY

 .../devicetree/bindings/phy/samsung-phy.txt|   24 +++
 drivers/gpu/drm/exynos/exynos_hdmi.c   |   11 +-
 drivers/media/platform/s5p-tv/hdmi_drv.c   |   11 +-
 drivers/phy/Kconfig|5 +
 drivers/phy/Makefile   |1 +
 drivers/phy/exynos-simple-phy.c|  154 
 6 files changed, 196 insertions(+), 10 deletions(-)
 create mode 100644 drivers/phy/exynos-simple-phy.c

-- 
1.7.9.5



[PATCH 4/4] Revert "drm/exynos: add mout_hdmi clock in hdmi driver to change parent"

2014-04-04 Thread Tomasz Stanislawski
This reverts commit 59956d35a8618235ea715280b49447bb36f2c975.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9a6d652..8ebb4bf 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -75,7 +75,6 @@ struct hdmi_resources {
struct clk  *sclk_pixel;
struct clk  *sclk_hdmiphy;
struct clk  *hdmiphy;
-   struct clk  *mout_hdmi;
struct regulator_bulk_data  *regul_bulk;
int regul_count;
 };
@@ -1282,7 +1281,7 @@ static void hdmi_v13_mode_apply(struct hdmi_context 
*hdata)
}

clk_disable_unprepare(hdata->res.sclk_hdmi);
-   clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
+   clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
clk_prepare_enable(hdata->res.sclk_hdmi);

/* enable HDMI and timing generator */
@@ -1449,7 +1448,7 @@ static void hdmi_v14_mode_apply(struct hdmi_context 
*hdata)
}

clk_disable_unprepare(hdata->res.sclk_hdmi);
-   clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
+   clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
clk_prepare_enable(hdata->res.sclk_hdmi);

/* enable HDMI and timing generator */
@@ -1475,7 +1474,7 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
u32 reg;

clk_disable_unprepare(hdata->res.sclk_hdmi);
-   clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
+   clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
clk_prepare_enable(hdata->res.sclk_hdmi);

/* operation mode */
@@ -1982,13 +1981,8 @@ static int hdmi_resources_init(struct hdmi_context 
*hdata)
DRM_ERROR("failed to get clock 'hdmiphy'\n");
goto fail;
}
-   res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
-   if (IS_ERR(res->mout_hdmi)) {
-   DRM_ERROR("failed to get clock 'mout_hdmi'\n");
-   goto fail;
-   }

-   clk_set_parent(res->mout_hdmi, res->sclk_pixel);
+   clk_set_parent(res->sclk_hdmi, res->sclk_pixel);

res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
sizeof(res->regul_bulk[0]), GFP_KERNEL);
-- 
1.7.9.5



[PATCH 3/4] clk: exynos4: enable clk_set_parent() propagation for sclk_hdmi and sclk_mixer clocks

2014-04-04 Thread Tomasz Stanislawski
This patch enables clk_set_parent() propagation for clocks used
by s5p-tv and exynos-drm drivers.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/clk/samsung/clk-exynos4.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c 
b/drivers/clk/samsung/clk-exynos4.c
index 528f8eb..87b8264 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -680,7 +680,8 @@ static struct samsung_gate_clock exynos4_gate_clks[] 
__initdata = {
 * the device name and clock alias names specified below for some
 * of the clocks can be removed.
 */
-   GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0),
+   GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0,
+   CLK_SET_PARENT_PARENT, 0),
GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif", SRC_MASK_PERIL1, 8, 0,
0),
GATE(CLK_JPEG, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0),
@@ -880,7 +881,8 @@ static struct samsung_gate_clock exynos4210_gate_clks[] 
__initdata = {
E4210_SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0),
GATE(CLK_SCLK_SATA, "sclk_sata", "div_sata",
SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
-   GATE(CLK_SCLK_MIXER, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0),
+   GATE(CLK_SCLK_MIXER, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4,
+   CLK_SET_PARENT_PARENT, 0),
GATE(CLK_SCLK_DAC, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0),
GATE(CLK_TSADC, "tsadc", "aclk100", GATE_IP_PERIL, 15,
0, 0),
-- 
1.7.9.5



[PATCH 2/4] clk: exynos4: export sclk_hdmiphy clock

2014-04-04 Thread Tomasz Stanislawski
Export sclk_hdmiphy clock to be usable from DT.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/clk/samsung/clk-exynos4.c   |2 +-
 include/dt-bindings/clock/exynos4.h |1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c 
b/drivers/clk/samsung/clk-exynos4.c
index b4f9672..528f8eb 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -428,7 +428,7 @@ static struct samsung_fixed_rate_clock 
exynos4_fixed_rate_ext_clks[] __initdata
 /* fixed rate clocks generated inside the soc */
 static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
FRATE(0, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 2400),
-   FRATE(0, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 2700),
+   FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 2700),
FRATE(0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 4800),
 };

diff --git a/include/dt-bindings/clock/exynos4.h 
b/include/dt-bindings/clock/exynos4.h
index 75aff33..0e245eb 100644
--- a/include/dt-bindings/clock/exynos4.h
+++ b/include/dt-bindings/clock/exynos4.h
@@ -33,6 +33,7 @@
 #define CLK_MOUT_MPLL_USER_C   18 /* Exynos4x12 only */
 #define CLK_MOUT_CORE  19
 #define CLK_MOUT_APLL  20
+#define CLK_SCLK_HDMIPHY   22

 /* gate for special clocks (sclk) */
 #define CLK_SCLK_FIMC0 128
-- 
1.7.9.5



[PATCH 1/4] clk: propagate parent change up one level

2014-04-04 Thread Tomasz Stanislawski
This patch adds support for propagation of setup of clock's parent one level
up.

This feature is helpful when a driver changes topology of its clocks using
clk_set_parent().  The problem occurs when on one platform/SoC driver's clock
is located at MUX output but on the other platform/SoC there is a gated proxy
clock between the MUX and driver's clock.  In such a case, driver's code has to
be modified to use one clock for enabling and the other clock for setup of a
parent.

The code updates are avoided by propagating setup of a parent up one level.

Additionally, this patch adds CLK_SET_PARENT_PARENT (sorry for naming) flag to
inform clk-core that clk_set_parent() should be propagated.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/clk/clk.c|6 ++
 include/linux/clk-provider.h |1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index dff0373..53bbfda 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1737,6 +1737,12 @@ int clk_set_parent(struct clk *clk, struct clk *parent)

/* try finding the new parent index */
if (parent) {
+   if ((clk->flags & CLK_SET_PARENT_PARENT)
+   && clk->num_parents == 1) {
+   ret = clk_set_parent(clk->parent, parent);
+   goto out;
+   }
+
p_index = clk_fetch_parent_index(clk, parent);
p_rate = parent->rate;
if (p_index < 0) {
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 5119174..daa0b03 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -30,6 +30,7 @@
 #define CLK_GET_RATE_NOCACHE   BIT(6) /* do not use the cached clk rate */
 #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
 #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy 
*/
+#define CLK_SET_PARENT_PARENT  BIT(9) /* propagate parent change up one level 
*/

 struct clk_hw;
 struct dentry;
-- 
1.7.9.5



[PATCH 0/4] Update to Exynos clocks

2014-04-04 Thread Tomasz Stanislawski
This patchset adds some updates to clocks for Exynos4 platform and to the clock
core.  The patches are rebased on linux/next.

An interesting part might be 'propagation of clk_set_parent()'.  This feature
simplifies configuration of complex topologyof clocks by drivers.  Such a
situation happens for Exynos HDMI driver.

The HDMI device is clocked by sclk_hdmi clock. In older versions of SoC and its
driver, the clock had two parent clocks: sclk_hdmiphy and sclk_pixel.
The sclk_hdmi was a gated clock.

In the recent version of Exynos clock provider this topology was slightly
changed. A new clock named mout_hdmi was introduced.  This new clock represents
the output of multiplexer that selects between sclk_hdmiphy and sclk_pixel.

After the change the sclk_hdmi is still gated but has a single parent -
mout_hdmi.

This change caused interesting situation in Exynos HDMI driver because this
driver used only sclk_hdmi.  Now clk_set_parent(sclk_hdmi, ...) fails because
sclk_hdmi has a single parent now.  Using mout_hdmi instead of sclk_hdmi will
not work because clk_enable(mout_hdmi) is not propagated to sclk_hdmi.

To solve this problem, the setup of mout_hdmi was added to Exynos HDMI in the
patch: "drm/exynos: add mout_hdmi clock in hdmi driver to change parent"

IMO, this change breaks abstraction of clock API reveling too detailed
information about clock topology to the driver.

Moreover, the driver no longer works with old DT bindings because they provide
no mout_hdmi clock.

The clock set_parent propagation can be used to fix this.  The clk_set_parent()
is propagated to a parent as long as the current clock has a single parent and
has the flag CLK_SET_PARENT_PARENT set.

Now Exynos HDMI can use only sclk_hdmi clock. The clk_enable() gates this clock
directly and clk_set_parent() is propagated to mout_hdmi.

This new behaviour does not break DT bindings because mout_hdmi would be simply
ignored.

After this change the 'add mout_hdmi clock' is no longer needed.

Regards,
Tomasz Stanislawski

Tomasz Stanislawski (4):
  clk: propagate parent change up one level
  clk: exynos4: export sclk_hdmiphy clock
  clk: exynos4: enable clk_set_parent() propagation for sclk_hdmi and
sclk_mixer clocks
  Revert "drm/exynos: add mout_hdmi clock in hdmi driver to change
parent"

 drivers/clk/clk.c|6 ++
 drivers/clk/samsung/clk-exynos4.c|8 +---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   14 --
 include/dt-bindings/clock/exynos4.h  |1 +
 include/linux/clk-provider.h |1 +
 5 files changed, 17 insertions(+), 13 deletions(-)

-- 
1.7.9.5



[PATCH v4 14/34] drm/exynos: hdmi: remove the i2c drivers and use devtree

2014-04-04 Thread Tomasz Stanislawski
Hi Inki,
Sorry for a very late reply.

On 02/19/2014 12:14 PM, Inki Dae wrote:
> Hi Tomasz,
> 
> 
> 2014-02-14 23:13 GMT+09:00 Tomasz Stanislawski :
>> Hi Daniel,
>> I think that it would be better to change the semantic of phy and ddc
>> bindings.
>>
>> Rather than pointing to I2C client it should point to I2C bus instead.
>> The exynos DRM driver can create dummy I2C clients using i2c_new_dummy()
>> function.
> 
> It seems better way. As of now, all we need for HDMI DDC is
> i2c_adapter (including i2c phy), not i2c_client.
> 
>>
>> There is quite strong rationale for this:
>> - DDC is always accessible on fixed addresses described in HDMI 
>> specification.
>> - HDMIPHY (including I2C address) is a part of HDMI IP and it is bound to
>>   specific version of Exynos SoC
>> - no need to add virtual nodes in DTS
> 
> You mean hdmiddc and hdmiphy nodes? If so, I think they are real
> nodes, not virtual nodes. Otherwise, plz give me more comments.
> 
> Thanks,
> Inki Dae
> 

The problem is that those nodes have no dedicated driver.
Moreover, the I2C address for HDMIPHY is always present on
a fixed address dependant on SoC (read HDMI IP) version.
Moreover, both devices share HDMI and HDMIPHY share registers
from HDMI's pool.
Additionally, the hdmiphy I2C client is currently configured using
exynos-hdmi code its DRM driver.
So technically the hdmiphy bus is only a resource used by
exynos-drm-hdmi driver.

Regards,
Tomasz Stanislawski

>> - NVIDIA already use bindings to DDC bus instead of DDC client. Take a look 
>> to
>>   arch/arm/boot/dts/tegra*.dts
>>
>> Regards,
>> Tomasz Stanislawski
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel



[PATCH v4 14/34] drm/exynos: hdmi: remove the i2c drivers and use devtree

2014-02-14 Thread Tomasz Stanislawski
Hi Daniel,
I think that it would be better to change the semantic of phy and ddc
bindings.

Rather than pointing to I2C client it should point to I2C bus instead.
The exynos DRM driver can create dummy I2C clients using i2c_new_dummy()
function.

There is quite strong rationale for this:
- DDC is always accessible on fixed addresses described in HDMI specification.
- HDMIPHY (including I2C address) is a part of HDMI IP and it is bound to
  specific version of Exynos SoC
- no need to add virtual nodes in DTS
- NVIDIA already use bindings to DDC bus instead of DDC client. Take a look to
  arch/arm/boot/dts/tegra*.dts

Regards,
Tomasz Stanislawski



[RFC 04/12] phy: Add simple-phy driver

2013-10-25 Thread Tomasz Stanislawski
Hi,
Please refer to the comments below.

On 10/24/2013 05:52 PM, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Monday 21 October 2013 07:48 PM, Tomasz Stanislawski wrote:
>> Add simple-phy driver to support a single register
>> PHY interfaces present on Exynos4 SoC.
> 
> How are these PHY interfaces modelled in the SoC? Where does the register
> actually reside?

Initially, I was planning to add PHY for HDMI_PHY register in
power management register set on s5pv310 soc.

However other PHYs use very similar interface (setting bit 0).
This includes DAC_PHY, ADC_PHY, PCIe_PHY, SATA_PHY.
Moreover it suits well to USBDEVICE_PHY, USBHOST_PHY.
That is why I thought about using something more generic
to handle all those phys without introducing a herd of
200-lines-long drivers.

>>
>> Signed-off-by: Tomasz Stanislawski 
>> ---
>>  drivers/phy/Kconfig  |5 ++
>>  drivers/phy/Makefile |1 +
>>  drivers/phy/phy-simple.c |  128 
>> ++
>>  3 files changed, 134 insertions(+)
>>  create mode 100644 drivers/phy/phy-simple.c
>>
>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index ac239ac..619c657 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -38,4 +38,9 @@ config TWL4030_USB
>>This transceiver supports high and full speed devices plus,
>>in host mode, low speed.
>>  
>> +config PHY_SIMPLE
>> +tristate "Simple PHY driver"
> 
> This is too generic a name to be used. Lets name it something specific to what
> it is used for (EXYNOS/HDMI.. ?).

Ok. It could be renamed to EXYNOS-SIMPLE-PHY or EXYNOS-1BIT-PHY or 
EXYNOS-GENERIC-PHY
or something similar. Any ideas?

>> +help
>> +  Support for PHY controllers configured using single register.
>> +
>>  endmenu
>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index 0dd8a98..3d68e19 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile
>> @@ -5,3 +5,4 @@
>>  obj-$(CONFIG_GENERIC_PHY)   += phy-core.o
>>  obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
>>  obj-$(CONFIG_TWL4030_USB)   += phy-twl4030-usb.o
>> +obj-$(CONFIG_PHY_SIMPLE)+= phy-simple.o
>> diff --git a/drivers/phy/phy-simple.c b/drivers/phy/phy-simple.c
>> new file mode 100644
>> index 000..4a28af7
>> --- /dev/null
>> +++ b/drivers/phy/phy-simple.c
>> @@ -0,0 +1,128 @@
>> +/*
>> + * Simple PHY driver
>> + *
>> + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
>> + * Author: Tomasz Stanislawski 
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +struct simple_phy {
>> +spinlock_t slock;
>> +u32 on_value;
>> +u32 off_value;
>> +u32 mask;
>> +void __iomem *regs;
>> +};
>> +
>> +static int sphy_set(struct simple_phy *sphy, bool on)
>> +{
>> +u32 reg;
>> +
>> +spin_lock(>slock);
> 
> Lets add spin_lock only when it is absolutely necessary. When your PHY 
> provider
> implements only a single PHY, it is not needed. phy_power_on and phy_power_off
> is already protected by the framework.

ok

>> +
>> +reg = readl(sphy->regs);
>> +reg &= ~sphy->mask;
>> +reg |= sphy->mask & (on ? sphy->on_value : sphy->off_value);
>> +writel(reg, sphy->regs);
>> +
>> +spin_unlock(>slock);
>> +
>> +return 0;
>> +}
>> +
>> +static int simple_phy_power_on(struct phy *phy)
>> +{
>> +return sphy_set(phy_get_drvdata(phy), 1);
>> +}
>> +
>> +static int simple_phy_power_off(struct phy *phy)
>> +{
>> +return sphy_set(phy_get_drvdata(phy), 0);
>> +}
>> +
>> +static struct phy_ops simple_phy_ops = {
>> +.power_on   = simple_phy_power_on,
>> +.power_off  = simple_phy_power_off,
>> +.owner  = THIS_MODULE,
>> +};
>> +
>> +static int simple_phy_probe(struct platform_device *pdev)
>> +{
>> +struct device *dev = >dev;
>> +struct simple_phy *sphy;
>> +struct resource *res;
>> +struct phy_provider *phy_provider;
>> +struct phy *phy;
>> +
>> +sphy = devm_kzalloc(dev, siz

[RFC 12/12] arm: dts: universal_c210: add HDMI devices

2013-10-21 Thread Tomasz Stanislawski
This patch adds configuration of HDMI devices on Universal C210 board.

Signed-off-by: Tomasz Stanislawski 
---
 arch/arm/boot/dts/exynos4210-universal_c210.dts |   53 +++
 1 file changed, 53 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts 
b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 889cdad..2d94a02 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -349,4 +349,57 @@
compatible = "samsung,s5p6440-pwm";
status = "okay";
};
+
+   hdmi_en: voltage-regulator-hdmi-5v {
+   compatible = "regulator-fixed";
+   regulator-name = "HDMI_5V";
+   regulator-min-microvolt = <500>;
+   regulator-max-microvolt = <500>;
+   gpio = < 1 0>;
+   enable-active-high;
+   };
+
+   i2c-ddc {
+   compatible = "i2c-gpio";
+   gpios = < 2 0  3 0>;
+   i2c-gpio,delay-us = <100>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   pinctrl-0 = <_ddc_bus>;
+   pinctrl-names = "default";
+   status = "okay";
+
+   hdmiddc at 72 {
+   compatible = "samsung,exynos5-hdmiddc";
+   reg = <0x72>;
+   };
+   };
+
+   hdmi: hdmi at 12D0 {
+   hpd-gpio = < 7 0>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_hpd>;
+   hdmi-en-supply = <_en>;
+   vdd-supply = <_reg>;
+   vdd_osc-supply = <_reg>;
+   vdd_pll-supply = <_reg>;
+   status = "okay";
+   };
+};
+
+_1 {
+   hdmi_hpd: hdmi-hpd {
+   samsung,pins = "gpx3-7";
+   samsung,pin-pud = <0>;
+   };
+};
+
+_0 {
+   i2c_ddc_bus: i2c-ddc-bus {
+   samsung,pins = "gpe4-2", "gpe4-3";
+   samsung,pin-function = <2>;
+   samsung,pin-pud = <3>;
+   samsung,pin-drv = <0>;
+   };
 };
-- 
1.7.9.5



[RFC 11/12] arm: dts: exynos4: add HDMI devices

2013-10-21 Thread Tomasz Stanislawski
This patch adds DT nodes for HDMI related devices on SoCs from Exynos4 family.

Signed-off-by: Tomasz Stanislawski 
---
 arch/arm/boot/dts/exynos4.dtsi|   27 +++
 arch/arm/boot/dts/exynos4210.dtsi |4 
 2 files changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index a5f6b8b..a5df9fe 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -522,4 +522,31 @@
samsung,power-domain = <_lcd0>;
status = "disabled";
};
+
+   hdmi_phy: hdmi-phy at 10020700 {
+   compatible = "simple-phy";
+   reg = <0x10020700 0x4>;
+   mask = <1>;
+   #phy-cells = <0>;
+   };
+
+   hdmi: hdmi at 12D0 {
+   reg = <0x12D0 0x7>;
+   interrupts = <0 92 0>;
+   clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy";
+   clocks = < 271>, < 136>, < 139>, < 21>;
+   phys = <_phy>;
+   phy-names = "hdmiphy";
+   status = "disabled";
+   samsung,power-domain = <_tv>;
+   };
+
+   mixer: mixer at 12C1 {
+   compatible = "samsung,exynos4-mixer";
+   interrupts = <0 91 0>;
+   reg = <0x12C1 0x2100>, <0x12c0 0x300>;
+   clock-names = "mixer", "sclk_hdmi", "vp", "sclk_dac", 
"sclk_mixer";
+   clocks = < 269>, < 136>, < 268>, < 
138>, < 137>;
+   samsung,power-domain = <_tv>;
+   };
 };
diff --git a/arch/arm/boot/dts/exynos4210.dtsi 
b/arch/arm/boot/dts/exynos4210.dtsi
index 057d682..75fd845 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -155,4 +155,8 @@
samsung,lcd-wb;
};
};
+
+   hdmi: hdmi at 12D0 {
+   compatible = "samsung,exynos4210-hdmi";
+   };
 };
-- 
1.7.9.5



[RFC 10/12] arm: dts: exynos4: add i2c controller for HDMIPHY

2013-10-21 Thread Tomasz Stanislawski
This patch adds DT nodes for I2C controller dedicated for HDMIPHY.

Signed-off-by: Tomasz Stanislawski 
---
 arch/arm/boot/dts/exynos4.dtsi |   16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index caadc02..a5f6b8b 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -36,6 +36,7 @@
i2c5 = _5;
i2c6 = _6;
i2c7 = _7;
+   i2c8 = _8;
csis0 = _0;
csis1 = _1;
fimc0 = _0;
@@ -399,6 +400,21 @@
status = "disabled";
};

+   i2c_8: i2c at 138E {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   compatible = "samsung,s3c2440-hdmiphy-i2c";
+   reg = <0x138E 0x100>;
+   interrupts = <0 93 0>;
+   clocks = < 325>;
+   clock-names = "i2c";
+
+   hdmiphy at 38 {
+   compatible = "samsung,exynos5-hdmiphy";
+   reg = <0x38>;
+   };
+   };
+
spi_0: spi at 1392 {
compatible = "samsung,exynos4210-spi";
reg = <0x1392 0x100>;
-- 
1.7.9.5



[RFC 09/12] drm: exynos: add compatibles for HDMI and Mixer chips and exynos4210 SoC

2013-10-21 Thread Tomasz Stanislawski
This patch add proper compatibles for Mixer and HDMI chip
available on exynos4210 SoCs.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c  |3 +++
 drivers/gpu/drm/exynos/exynos_mixer.c |3 +++
 2 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 5adb5c1..ae21fa5 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1874,6 +1874,9 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata

 static struct of_device_id hdmi_match_types[] = {
{
+   .compatible = "samsung,exynos4210-hdmi",
+   .data   = (void *)HDMI_TYPE13,
+   }, {
.compatible = "samsung,exynos5-hdmi",
.data   = (void *)HDMI_TYPE14,
}, {
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index 63bc5f9..892afb5 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1161,6 +1161,9 @@ static struct platform_device_id mixer_driver_types[] = {

 static struct of_device_id mixer_match_types[] = {
{
+   .compatible = "samsung,exynos4-mixer",
+   .data   = _mxr_drv_data,
+   }, {
.compatible = "samsung,exynos5-mixer",
.data   = _mxr_drv_data,
}, {
-- 
1.7.9.5



[RFC 08/12] drm: exynos: hdmi: simplify extracting hpd-gpio from DT

2013-10-21 Thread Tomasz Stanislawski
This patch eliminates redundant checks while retrieving HPD gpio from DT during
HDMI's probe().

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index e36588a..5adb5c1 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1858,23 +1858,18 @@ static struct s5p_hdmi_platform_data 
*drm_hdmi_dt_parse_pdata
 {
struct device_node *np = dev->of_node;
struct s5p_hdmi_platform_data *pd;
-   u32 value;

pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd)
-   goto err_data;
+   return NULL;

-   if (!of_find_property(np, "hpd-gpio", )) {
+   pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, NULL);
+   if (pd->hpd_gpio < 0) {
DRM_ERROR("no hpd gpio property found\n");
-   goto err_data;
+   return NULL;
}

-   pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
-
return pd;
-
-err_data:
-   return NULL;
 }

 static struct of_device_id hdmi_match_types[] = {
-- 
1.7.9.5



[RFC 07/12] drm: exynos: hdmi: use hdmiphy as PHY

2013-10-21 Thread Tomasz Stanislawski
The HDMIPHY (physical interface) is controlled by a single
bit in a power controller's regiter. It was implemented
as clock. It was a simple but effective hack.

This patch makes HDMI driver to control HDMIPHY via PHY interface.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index fcfa23a..e36588a 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 

@@ -82,7 +83,7 @@ struct hdmi_resources {
struct clk  *sclk_hdmi;
struct clk  *sclk_pixel;
struct clk  *sclk_hdmiphy;
-   struct clk  *hdmiphy;
+   struct phy  *hdmiphy;
struct regulator_bulk_data  *regul_bulk;
int regul_count;
 };
@@ -1685,7 +1686,7 @@ static void hdmi_poweron(struct hdmi_context *hdata)
if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
DRM_DEBUG_KMS("failed to enable regulator bulk\n");

-   clk_prepare_enable(res->hdmiphy);
+   phy_power_on(res->hdmiphy);
clk_prepare_enable(res->hdmi);
clk_prepare_enable(res->sclk_hdmi);

@@ -1710,7 +1711,7 @@ static void hdmi_poweroff(struct hdmi_context *hdata)

clk_disable_unprepare(res->sclk_hdmi);
clk_disable_unprepare(res->hdmi);
-   clk_disable_unprepare(res->hdmiphy);
+   phy_power_off(res->hdmiphy);
regulator_bulk_disable(res->regul_count, res->regul_bulk);

mutex_lock(>hdmi_mutex);
@@ -1809,9 +1810,9 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
goto fail;
}
-   res->hdmiphy = devm_clk_get(dev, "hdmiphy");
+   res->hdmiphy = devm_phy_get(dev, "hdmiphy");
if (IS_ERR(res->hdmiphy)) {
-   DRM_ERROR("failed to get clock 'hdmiphy'\n");
+   DRM_ERROR("failed to get phy 'hdmiphy'\n");
goto fail;
}

-- 
1.7.9.5



[RFC 05/12] phy: use of_phy_simple_xlate for NULL xlate function

2013-10-21 Thread Tomasz Stanislawski
Use default handler of_phy_simple_xlate() when NULL is passed as argument to
of_phy_provider_register().

Signed-off-by: Tomasz Stanislawski 
---
 drivers/phy/phy-core.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 03cf8fb..c38ae1e7 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -575,7 +575,7 @@ struct phy_provider *__of_phy_provider_register(struct 
device *dev,

phy_provider->dev = dev;
phy_provider->owner = owner;
-   phy_provider->of_xlate = of_xlate;
+   phy_provider->of_xlate = of_xlate ? of_xlate : of_phy_simple_xlate;

mutex_lock(_provider_mutex);
list_add_tail(_provider->list, _provider_list);
-- 
1.7.9.5



[RFC 04/12] phy: Add simple-phy driver

2013-10-21 Thread Tomasz Stanislawski
Add simple-phy driver to support a single register
PHY interfaces present on Exynos4 SoC.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/phy/Kconfig  |5 ++
 drivers/phy/Makefile |1 +
 drivers/phy/phy-simple.c |  128 ++
 3 files changed, 134 insertions(+)
 create mode 100644 drivers/phy/phy-simple.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index ac239ac..619c657 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -38,4 +38,9 @@ config TWL4030_USB
  This transceiver supports high and full speed devices plus,
  in host mode, low speed.

+config PHY_SIMPLE
+   tristate "Simple PHY driver"
+   help
+ Support for PHY controllers configured using single register.
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 0dd8a98..3d68e19 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_GENERIC_PHY)  += phy-core.o
 obj-$(CONFIG_OMAP_USB2)+= phy-omap-usb2.o
 obj-$(CONFIG_TWL4030_USB)  += phy-twl4030-usb.o
+obj-$(CONFIG_PHY_SIMPLE)   += phy-simple.o
diff --git a/drivers/phy/phy-simple.c b/drivers/phy/phy-simple.c
new file mode 100644
index 000..4a28af7
--- /dev/null
+++ b/drivers/phy/phy-simple.c
@@ -0,0 +1,128 @@
+/*
+ * Simple PHY driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Tomasz Stanislawski 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct simple_phy {
+   spinlock_t slock;
+   u32 on_value;
+   u32 off_value;
+   u32 mask;
+   void __iomem *regs;
+};
+
+static int sphy_set(struct simple_phy *sphy, bool on)
+{
+   u32 reg;
+
+   spin_lock(>slock);
+
+   reg = readl(sphy->regs);
+   reg &= ~sphy->mask;
+   reg |= sphy->mask & (on ? sphy->on_value : sphy->off_value);
+   writel(reg, sphy->regs);
+
+   spin_unlock(>slock);
+
+   return 0;
+}
+
+static int simple_phy_power_on(struct phy *phy)
+{
+   return sphy_set(phy_get_drvdata(phy), 1);
+}
+
+static int simple_phy_power_off(struct phy *phy)
+{
+   return sphy_set(phy_get_drvdata(phy), 0);
+}
+
+static struct phy_ops simple_phy_ops = {
+   .power_on   = simple_phy_power_on,
+   .power_off  = simple_phy_power_off,
+   .owner  = THIS_MODULE,
+};
+
+static int simple_phy_probe(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   struct simple_phy *sphy;
+   struct resource *res;
+   struct phy_provider *phy_provider;
+   struct phy *phy;
+
+   sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
+   if (!sphy)
+   return -ENOMEM;
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+   sphy->regs = devm_ioremap_resource(dev, res);
+   if (IS_ERR(sphy->regs)) {
+   dev_err(dev, "failed to ioremap registers\n");
+   return PTR_ERR(sphy->regs);
+   }
+
+   spin_lock_init(>slock);
+
+   phy_provider = devm_of_phy_provider_register(dev, NULL);
+   if (IS_ERR(phy_provider)) {
+   dev_err(dev, "failed to register PHY provider\n");
+   return PTR_ERR(phy_provider);
+   }
+
+   phy = devm_phy_create(dev, _phy_ops, NULL);
+   if (IS_ERR(phy)) {
+   dev_err(dev, "failed to create PHY\n");
+   return PTR_ERR(phy);
+   }
+
+   sphy->mask = 1;
+   sphy->on_value = ~0;
+   sphy->off_value = 0;
+
+   of_property_read_u32(dev->of_node, "mask", >mask);
+   of_property_read_u32(dev->of_node, "on-value", >on_value);
+   of_property_read_u32(dev->of_node, "off-value", >off_value);
+
+   phy_set_drvdata(phy, sphy);
+
+   dev_info(dev, "probe successful\n");
+
+   return 0;
+}
+
+static const struct of_device_id simple_phy_of_match[] = {
+   { .compatible = "simple-phy" },
+   { },
+};
+MODULE_DEVICE_TABLE(of, simple_phy_of_match);
+
+static struct platform_driver simple_phy_driver = {
+   .probe  = simple_phy_probe,
+   .driver = {
+   .of_match_table = simple_phy_of_match,
+   .name  = "simple-phy",
+   .owner = THIS_MODULE,
+   }
+};
+module_platform_driver(simple_phy_driver);
+
+MODULE_DESCRIPTION("Simple PHY driver");
+MODULE_AUTHOR("Tomasz Stanislawski ");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5



[RFC 03/12] clk: exynos4: enable clk_set_parent() propagation for sclk_hdmi and sclk_mixer clocks

2013-10-21 Thread Tomasz Stanislawski
This patch enables clk_set_parent() propagation for clocks used
by s5p-tv and exynos-drm drivers.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/clk/samsung/clk-exynos4.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c 
b/drivers/clk/samsung/clk-exynos4.c
index df79ca6..1f58b7c 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -605,7 +605,8 @@ static struct samsung_gate_clock exynos4_gate_clks[] 
__initdata = {
 * the device name and clock alias names specified below for some
 * of the clocks can be removed.
 */
-   GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0),
+   GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0,
+   CLK_SET_PARENT_PARENT, 0),
GATE(sclk_spdif, "sclk_spdif", "mout_spdif", SRC_MASK_PERIL1, 8, 0, 0),
GATE(jpeg, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0),
GATE(mie0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0),
@@ -801,7 +802,8 @@ static struct samsung_gate_clock exynos4210_gate_clks[] 
__initdata = {
E4210_SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0),
GATE(sclk_sata, "sclk_sata", "div_sata",
SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
-   GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0),
+   GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4,
+   CLK_SET_PARENT_PARENT, 0),
GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0),
GATE(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15,
0, 0),
-- 
1.7.9.5



[RFC 02/12] clk: exynos4: export sclk_hdmiphy clock

2013-10-21 Thread Tomasz Stanislawski
Export sclk_hdmiphy clock to be usable from DT.

Signed-off-by: Tomasz Stanislawski 
---
 .../devicetree/bindings/clock/exynos4-clock.txt|1 +
 drivers/clk/samsung/clk-exynos4.c  |4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt 
b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
index c6bf8a6..cb08f5d 100644
--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
@@ -46,6 +46,7 @@ Exynos4 SoC and this is specified where applicable.
   mout_mpll_user_c18  Exynos4x12
   mout_core   19
   mout_apll   20
+  sclk_hdmiphy21


 [Clock Gate for Special Clocks]
diff --git a/drivers/clk/samsung/clk-exynos4.c 
b/drivers/clk/samsung/clk-exynos4.c
index ad5ff50..df79ca6 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -148,7 +148,7 @@ enum exynos4_clks {
xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100,
aclk160, aclk133, mout_mpll_user_t, mout_mpll_user_c, mout_core,
-   mout_apll, /* 20 */
+   mout_apll, sclk_hdmiphy, /* 21 */

/* gate for special clocks (sclk) */
sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
@@ -354,7 +354,7 @@ static struct samsung_fixed_rate_clock 
exynos4_fixed_rate_ext_clks[] __initdata
 /* fixed rate clocks generated inside the soc */
 static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 2400),
-   FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 2700),
+   FRATE(sclk_hdmiphy, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 2700),
FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 4800),
 };

-- 
1.7.9.5



[RFC 01/12] clk: propagate parent change up one level

2013-10-21 Thread Tomasz Stanislawski
This patch adds support for propagation of setup of clock's parent one level
up.

This feature is helpful when a driver changes topology of its clocks using
clk_set_parent().  The problem occurs when on one platform/SoC driver's clock
is located at MUX output but on the other platform/SoC there is a gated proxy
clock between the MUX and driver's clock.  In such a case, driver's code has to
be modified to use one clock for enabling and the other clock for setup of a
parent.

The code updates are avoided by propagating setup of a parent up one level.

Additionally, this patch adds CLK_SET_PARENT_PARENT (sorry for naming) flag to
inform clk-core that clk_set_parent() should be propagated.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/clk/clk.c|6 ++
 include/linux/clk-provider.h |1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index a004769..14eda80 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1595,6 +1595,12 @@ int clk_set_parent(struct clk *clk, struct clk *parent)

/* try finding the new parent index */
if (parent) {
+   if ((clk->flags & CLK_SET_PARENT_PARENT)
+   && clk->num_parents == 1) {
+   ret = clk_set_parent(clk->parent, parent);
+   goto out;
+   }
+
p_index = clk_fetch_parent_index(clk, parent);
p_rate = parent->rate;
if (p_index == clk->num_parents) {
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 73bdb69..83c98d5 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -29,6 +29,7 @@
 #define CLK_IS_BASIC   BIT(5) /* Basic clk, can't do a to_clk_foo() */
 #define CLK_GET_RATE_NOCACHE   BIT(6) /* do not use the cached clk rate */
 #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
+#define CLK_SET_PARENT_PARENT  BIT(8) /* propagate parent change up one level 
*/

 struct clk_hw;

-- 
1.7.9.5



[RFC 00/12] Add DRM Exynos HDMI on SoCs from Exynos4 family

2013-10-21 Thread Tomasz Stanislawski
This patchset adds support for HDMI at SoCs from Exynos4 family. The patches
are rebased on kishon/next. Additionally, The patchset contains small fixes to
PHY and CLK frameworks.  I preferred to keep all the patches together for the
first version of the RFC.

The interesting part might be 'propagation of clk_set_parent()'.  This feature
allows to remove the usage of artificial clocks in drivers.  Such a situation
happens for Exynos HDMI and 'mout_hdmi' where the clock is not even mentioned in
some versions of SoC's documentation. Since enabling and setting rate can be
propagated I think that clk_set_parent() should also be propagated. This would
simplify driver's code and make it less dependant on SoC's version.

Another interesting feature refers to simple PHY driver.  This driver register
a PHY interface that operates by setting a special bit in platform register.
This situation is very common in Exynos SoCs.  The current version supports
only one phy per node.  The code might be modified to support multiple phys
from single simple-phy provider to avoid creation of multiple nodes in DT.

All comments are welcome.

Regards,
Tomasz Stanislawski


Tomasz Stanislawski (12):
  clk: propagate parent change up one level
  clk: exynos4: export sclk_hdmiphy clock
  clk: exynos4: enable clk_set_parent() propagation for sclk_hdmi and
sclk_mixer clocks
  phy: Add simple-phy driver
  phy: use of_phy_simple_xlate for NULL xlate function
  Revert "drm/exynos: add mout_hdmi clock in hdmi driver to change
parent"
  drm: exynos: hdmi: use hdmiphy as PHY
  drm: exynos: hdmi: simplify extracting hpd-gpio from DT
  drm: exynos: add compatibles for HDMI and Mixer chips and exynos4210
SoC
  arm: dts: exynos4: add i2c controller for HDMIPHY
  arm: dts: exynos4: add HDMI devices
  arm: dts: universal_c210: add HDMI devices

 .../devicetree/bindings/clock/exynos4-clock.txt|1 +
 arch/arm/boot/dts/exynos4.dtsi |   43 +++
 arch/arm/boot/dts/exynos4210-universal_c210.dts|   53 
 arch/arm/boot/dts/exynos4210.dtsi  |4 +
 drivers/clk/clk.c  |6 +
 drivers/clk/samsung/clk-exynos4.c  |   10 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c   |   41 +++
 drivers/gpu/drm/exynos/exynos_mixer.c  |3 +
 drivers/phy/Kconfig|5 +
 drivers/phy/Makefile   |1 +
 drivers/phy/phy-core.c |2 +-
 drivers/phy/phy-simple.c   |  128 
 include/linux/clk-provider.h   |1 +
 13 files changed, 269 insertions(+), 29 deletions(-)
 create mode 100644 drivers/phy/phy-simple.c

-- 
1.7.9.5



[PATCHv10 23/26] v4l: vb2-dma-contig: align buffer size to PAGE_SIZE

2012-10-12 Thread Tomasz Stanislawski
Hi Laurent,

On 10/11/2012 11:31 PM, Laurent Pinchart wrote:
> Hi Tomasz,
> 
> On Wednesday 10 October 2012 16:46:42 Tomasz Stanislawski wrote:
>> Most operations on DMA and DMABUF framework need page
>> aligned buffers.
> 
> The comment is a bit misleading, the buffer is already page-aligned (unless 
> I'm mistaken dma_alloc_coherent() returns a page-aligned buffer) but its size 
> isn't a multiple of the page size.

Ok. I will update the commit message that only buffer size is going to be page 
aligned.

> 
> Do we really need a page size multiple ? Isn't it enough to make the size a 
> multiple of the cache line size ?
> 

Frankly, I strongly oppose forcing a size of a DMA buffer to be rounded up.

However, I discovered a problem while testing mmap() interface in dma-buf.
The test in dma_buf_mmap() will fail if the size is not a multiple of 4k.

Maybe the value from dma-buf.c:456 should be changed from:

dmabuf->size >> PAGE_SHIFT

to

PAGE_ALIGN(dmabuf->size) >> PAGE_SHIFT

However, I preferred to avoid any changes outside of the media tree
hoping that the patchset gets merged. Rounding the buffer size to
a page size was quick workaround for the issue with DMABUF mmap().

Regards,
Tomasz Stanislawski

>> This fix guarantees this requirement
>> for vb2-dma-contig buffers.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> ---
>>  drivers/media/v4l2-core/videobuf2-dma-contig.c |3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 571a919..002ee50
>> 100644
>> --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> @@ -162,6 +162,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long
>> size) if (!buf)
>>  return ERR_PTR(-ENOMEM);
>>
>> +/* align image size to PAGE_SIZE */
>> +size = PAGE_ALIGN(size);
>> +
>>  buf->vaddr = dma_alloc_coherent(dev, size, >dma_addr, GFP_KERNEL);
>>  if (!buf->vaddr) {
>>  dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);



[PATCHv10 22/26] v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

2012-10-12 Thread Tomasz Stanislawski
Hi Laurent,
Thank you for the review.
Please refer to the comments below.

On 10/11/2012 11:36 PM, Laurent Pinchart wrote:
> Hi Tomasz,
> 
> Thanks for the patch.
> 
> On Wednesday 10 October 2012 16:46:41 Tomasz Stanislawski wrote:
>> From: Marek Szyprowski 
>>
>> The DMA transfer must be aligned to a specific value. If userptr is not
>> aligned to DMA requirements then unexpected corruptions of the memory may
>> occur before or after a buffer.  To prevent such situations, all unligned
>> userptr buffers are rejected at VIDIOC_QBUF.
>>
>> Signed-off-by: Marek Szyprowski 
>> Acked-by: Hans Verkuil 
>> ---
>>  drivers/media/v4l2-core/videobuf2-dma-contig.c |   12 
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 2d661fd..571a919
>> 100644
>> --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> @@ -493,6 +493,18 @@ static void *vb2_dc_get_userptr(void *alloc_ctx,
>> unsigned long vaddr, struct vm_area_struct *vma;
>>  struct sg_table *sgt;
>>  unsigned long contig_size;
>> +unsigned long dma_align = dma_get_cache_alignment();
>> +
>> +/* Only cache aligned DMA transfers are reliable */
>> +if (!IS_ALIGNED(vaddr | size, dma_align)) {
>> +pr_debug("user data must be aligned to %lu bytes\n", dma_align);
>> +return ERR_PTR(-EINVAL);
>> +}
> 
> Looks good to me.
> 
>> +if (!size) {
>> +pr_debug("size is zero\n");
>> +return ERR_PTR(-EINVAL);
>> +}
> 
> Can this happen ? The vb2 core already has
> 
> /* Check if the provided plane buffer is large enough */
> if (planes[plane].length < q->plane_sizes[plane]) {
> ret = -EINVAL;
> goto err;
> }
> 
> Unless queue_setup sets plane_sizes to 0 we can't reach vb2_dc_get_userptr.
> 

Yes.. unfortunately, some drivers set plane_size to 0 at queue_setup.
Especially, if REQBUFS is called before any S_FMT.
Maybe it is just a driver bug.

However, VB2 makes no sanity check if plane_sizes[] is zero.
I was not able to find in Documentation nor code comments
any explicit statement that plane_size cannot be zero.

Therefore I have to reject reject a 0-bytes-long user pointer
at vb2_dc_get_userptr before creating an empty scatterlist
and passing it to the DMA layer.

Regards,
Tomasz Stanislawski

>>  buf = kzalloc(sizeof *buf, GFP_KERNEL);
>>  if (!buf)
> 



[PATCHv10 21/26] v4l: vb2-dma-contig: add reference counting for a device from allocator context

2012-10-12 Thread Tomasz Stanislawski
Hi Laurent,
Thank your your review.

On 10/11/2012 11:49 PM, Laurent Pinchart wrote:
> Hi Tomasz,
> 
> Thanks for the patch.
> 
> On Wednesday 10 October 2012 16:46:40 Tomasz Stanislawski wrote:
>> This patch adds taking reference to the device for MMAP buffers.
>>
>> Such buffers, may be exported using DMABUF mechanism. If the driver that
>> created a queue is unloaded then the queue is released, the device might be
>> released too.  However, buffers cannot be released if they are referenced by
>> DMABUF descriptor(s). The device pointer kept in a buffer must be valid for
>> the whole buffer's lifetime. Therefore MMAP buffers should take a reference
>> to the device to avoid risk of dangling pointers.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> Acked-by: Hans Verkuil 
> 
> Acked-by: Laurent Pinchart 
> 
> But two small comments below.
> 
>> ---
>>  drivers/media/v4l2-core/videobuf2-dma-contig.c |4 
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> b/drivers/media/v4l2-core/videobuf2-dma-contig.c index b138b5c..2d661fd
>> 100644
>> --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
>> @@ -148,6 +148,7 @@ static void vb2_dc_put(void *buf_priv)
>>  kfree(buf->sgt_base);
>>  }
>>  dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
>> +put_device(buf->dev);
>>  kfree(buf);
>>  }
>>
>> @@ -168,6 +169,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long
>> size) return ERR_PTR(-ENOMEM);
>>  }
>>
>> +/* prevent the device from release while the buffer is exported */
> 
> s/prevent/Prevent/ ?
> 

s/release/being released/ ?

>> +get_device(dev);
>> +
>>  buf->dev = dev;
> 
> What about just
> 
>   buf->dev = get_device(dev);
> 

Right, sorry I missed that from your previous review :).

Regards,
Tomasz Stanislawski

>>  buf->size = size;



Re: [PATCHv10 22/26] v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

2012-10-12 Thread Tomasz Stanislawski
Hi Laurent,
Thank you for the review.
Please refer to the comments below.

On 10/11/2012 11:36 PM, Laurent Pinchart wrote:
 Hi Tomasz,
 
 Thanks for the patch.
 
 On Wednesday 10 October 2012 16:46:41 Tomasz Stanislawski wrote:
 From: Marek Szyprowski m.szyprow...@samsung.com

 The DMA transfer must be aligned to a specific value. If userptr is not
 aligned to DMA requirements then unexpected corruptions of the memory may
 occur before or after a buffer.  To prevent such situations, all unligned
 userptr buffers are rejected at VIDIOC_QBUF.

 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 Acked-by: Hans Verkuil hans.verk...@cisco.com
 ---
  drivers/media/v4l2-core/videobuf2-dma-contig.c |   12 
  1 file changed, 12 insertions(+)

 diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c
 b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 2d661fd..571a919
 100644
 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
 +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
 @@ -493,6 +493,18 @@ static void *vb2_dc_get_userptr(void *alloc_ctx,
 unsigned long vaddr, struct vm_area_struct *vma;
  struct sg_table *sgt;
  unsigned long contig_size;
 +unsigned long dma_align = dma_get_cache_alignment();
 +
 +/* Only cache aligned DMA transfers are reliable */
 +if (!IS_ALIGNED(vaddr | size, dma_align)) {
 +pr_debug(user data must be aligned to %lu bytes\n, dma_align);
 +return ERR_PTR(-EINVAL);
 +}
 
 Looks good to me.
 
 +if (!size) {
 +pr_debug(size is zero\n);
 +return ERR_PTR(-EINVAL);
 +}
 
 Can this happen ? The vb2 core already has
 
 /* Check if the provided plane buffer is large enough */
 if (planes[plane].length  q-plane_sizes[plane]) {
 ret = -EINVAL;
 goto err;
 }
 
 Unless queue_setup sets plane_sizes to 0 we can't reach vb2_dc_get_userptr.
 

Yes.. unfortunately, some drivers set plane_size to 0 at queue_setup.
Especially, if REQBUFS is called before any S_FMT.
Maybe it is just a driver bug.

However, VB2 makes no sanity check if plane_sizes[] is zero.
I was not able to find in Documentation nor code comments
any explicit statement that plane_size cannot be zero.

Therefore I have to reject reject a 0-bytes-long user pointer
at vb2_dc_get_userptr before creating an empty scatterlist
and passing it to the DMA layer.

Regards,
Tomasz Stanislawski

  buf = kzalloc(sizeof *buf, GFP_KERNEL);
  if (!buf)
 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCHv10 23/26] v4l: vb2-dma-contig: align buffer size to PAGE_SIZE

2012-10-12 Thread Tomasz Stanislawski
Hi Laurent,

On 10/11/2012 11:31 PM, Laurent Pinchart wrote:
 Hi Tomasz,
 
 On Wednesday 10 October 2012 16:46:42 Tomasz Stanislawski wrote:
 Most operations on DMA and DMABUF framework need page
 aligned buffers.
 
 The comment is a bit misleading, the buffer is already page-aligned (unless 
 I'm mistaken dma_alloc_coherent() returns a page-aligned buffer) but its size 
 isn't a multiple of the page size.

Ok. I will update the commit message that only buffer size is going to be page 
aligned.

 
 Do we really need a page size multiple ? Isn't it enough to make the size a 
 multiple of the cache line size ?
 

Frankly, I strongly oppose forcing a size of a DMA buffer to be rounded up.

However, I discovered a problem while testing mmap() interface in dma-buf.
The test in dma_buf_mmap() will fail if the size is not a multiple of 4k.

Maybe the value from dma-buf.c:456 should be changed from:

dmabuf-size  PAGE_SHIFT

to

PAGE_ALIGN(dmabuf-size)  PAGE_SHIFT

However, I preferred to avoid any changes outside of the media tree
hoping that the patchset gets merged. Rounding the buffer size to
a page size was quick workaround for the issue with DMABUF mmap().

Regards,
Tomasz Stanislawski

 This fix guarantees this requirement
 for vb2-dma-contig buffers.

 Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
 ---
  drivers/media/v4l2-core/videobuf2-dma-contig.c |3 +++
  1 file changed, 3 insertions(+)

 diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c
 b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 571a919..002ee50
 100644
 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
 +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
 @@ -162,6 +162,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long
 size) if (!buf)
  return ERR_PTR(-ENOMEM);

 +/* align image size to PAGE_SIZE */
 +size = PAGE_ALIGN(size);
 +
  buf-vaddr = dma_alloc_coherent(dev, size, buf-dma_addr, GFP_KERNEL);
  if (!buf-vaddr) {
  dev_err(dev, dma_alloc_coherent of size %ld failed\n, size);

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 26/26] v4l: s5p-mfc: support for dmabuf exporting

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-mfc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: Kamil Debski 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-mfc/s5p_mfc_dec.c |   14 ++
 drivers/media/platform/s5p-mfc/s5p_mfc_enc.c |   14 ++
 2 files changed, 28 insertions(+)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index eb6a70b..6dad9a7 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -636,6 +636,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
return -EINVAL;
 }

+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+
+   if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+   return vb2_expbuf(>vq_src, eb);
+   if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+   return vb2_expbuf(>vq_dst, eb);
+   return -EINVAL;
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
   enum v4l2_buf_type type)
@@ -813,6 +826,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+   .vidioc_expbuf = vidioc_expbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_crop = vidioc_g_crop,
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 2af6d52..22bf684 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -1165,6 +1165,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
return ret;
 }

+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+
+   if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+   return vb2_expbuf(>vq_src, eb);
+   if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+   return vb2_expbuf(>vq_dst, eb);
+   return -EINVAL;
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
   enum v4l2_buf_type type)
@@ -1568,6 +1581,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops 
= {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+   .vidioc_expbuf = vidioc_expbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_s_parm = vidioc_s_parm,
-- 
1.7.9.5



[PATCHv10 25/26] v4l: s5p-tv: mixer: support for dmabuf exporting

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-tv/mixer_video.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/media/platform/s5p-tv/mixer_video.c 
b/drivers/media/platform/s5p-tv/mixer_video.c
index 2421e527..5e3cdb2 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -698,6 +698,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct 
v4l2_buffer *p)
return vb2_dqbuf(>vb_queue, p, file->f_flags & O_NONBLOCK);
 }

+static int mxr_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct mxr_layer *layer = video_drvdata(file);
+
+   mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
+   return vb2_expbuf(>vb_queue, eb);
+}
+
 static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
struct mxr_layer *layer = video_drvdata(file);
@@ -725,6 +734,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
.vidioc_querybuf = mxr_querybuf,
.vidioc_qbuf = mxr_qbuf,
.vidioc_dqbuf = mxr_dqbuf,
+   .vidioc_expbuf = mxr_expbuf,
/* Streaming control */
.vidioc_streamon = mxr_streamon,
.vidioc_streamoff = mxr_streamoff,
-- 
1.7.9.5



[PATCHv10 24/26] v4l: s5p-fimc: support for dmabuf exporting

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: Sylwester Nawrocki 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-fimc/fimc-capture.c |9 +
 drivers/media/platform/s5p-fimc/fimc-m2m.c |   10 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c 
b/drivers/media/platform/s5p-fimc/fimc-capture.c
index 246bb32..e5fd159 100644
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -1231,6 +1231,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
return vb2_qbuf(>vid_cap.vbq, buf);
 }

+static int fimc_cap_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+   struct fimc_dev *fimc = video_drvdata(file);
+
+   return vb2_expbuf(>vid_cap.vbq, eb);
+}
+
 static int fimc_cap_dqbuf(struct file *file, void *priv,
   struct v4l2_buffer *buf)
 {
@@ -1355,6 +1363,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops 
= {

.vidioc_qbuf= fimc_cap_qbuf,
.vidioc_dqbuf   = fimc_cap_dqbuf,
+   .vidioc_expbuf  = fimc_cap_expbuf,

.vidioc_prepare_buf = fimc_cap_prepare_buf,
.vidioc_create_bufs = fimc_cap_create_bufs,
diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c 
b/drivers/media/platform/s5p-fimc/fimc-m2m.c
index 17067a7..1cd4fcf 100644
--- a/drivers/media/platform/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c
@@ -439,6 +439,15 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh,
return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
 }

+static int fimc_m2m_expbuf(struct file *file, void *fh,
+   struct v4l2_exportbuffer *eb)
+{
+   struct fimc_ctx *ctx = fh_to_ctx(fh);
+
+   return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
+}
+
+
 static int fimc_m2m_streamon(struct file *file, void *fh,
 enum v4l2_buf_type type)
 {
@@ -607,6 +616,7 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
.vidioc_querybuf= fimc_m2m_querybuf,
.vidioc_qbuf= fimc_m2m_qbuf,
.vidioc_dqbuf   = fimc_m2m_dqbuf,
+   .vidioc_expbuf  = fimc_m2m_expbuf,
.vidioc_streamon= fimc_m2m_streamon,
.vidioc_streamoff   = fimc_m2m_streamoff,
.vidioc_g_crop  = fimc_m2m_g_crop,
-- 
1.7.9.5



[PATCHv10 23/26] v4l: vb2-dma-contig: align buffer size to PAGE_SIZE

2012-10-10 Thread Tomasz Stanislawski
Most operations on DMA and DMABUF framework need page
aligned buffers. This fix guarantees this requirement
for vb2-dma-contig buffers.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 571a919..002ee50 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -162,6 +162,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
if (!buf)
return ERR_PTR(-ENOMEM);

+   /* align image size to PAGE_SIZE */
+   size = PAGE_ALIGN(size);
+
buf->vaddr = dma_alloc_coherent(dev, size, >dma_addr, GFP_KERNEL);
if (!buf->vaddr) {
dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
-- 
1.7.9.5



[PATCHv10 22/26] v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski 

The DMA transfer must be aligned to a specific value. If userptr is not aligned
to DMA requirements then unexpected corruptions of the memory may occur before
or after a buffer.  To prevent such situations, all unligned userptr buffers
are rejected at VIDIOC_QBUF.

Signed-off-by: Marek Szyprowski 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 2d661fd..571a919 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -493,6 +493,18 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned 
long vaddr,
struct vm_area_struct *vma;
struct sg_table *sgt;
unsigned long contig_size;
+   unsigned long dma_align = dma_get_cache_alignment();
+
+   /* Only cache aligned DMA transfers are reliable */
+   if (!IS_ALIGNED(vaddr | size, dma_align)) {
+   pr_debug("user data must be aligned to %lu bytes\n", dma_align);
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (!size) {
+   pr_debug("size is zero\n");
+   return ERR_PTR(-EINVAL);
+   }

buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
-- 
1.7.9.5



[PATCHv10 21/26] v4l: vb2-dma-contig: add reference counting for a device from allocator context

2012-10-10 Thread Tomasz Stanislawski
This patch adds taking reference to the device for MMAP buffers.

Such buffers, may be exported using DMABUF mechanism. If the driver that
created a queue is unloaded then the queue is released, the device might be
released too.  However, buffers cannot be released if they are referenced by
DMABUF descriptor(s). The device pointer kept in a buffer must be valid for the
whole buffer's lifetime. Therefore MMAP buffers should take a reference to the
device to avoid risk of dangling pointers.

Signed-off-by: Tomasz Stanislawski 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index b138b5c..2d661fd 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -148,6 +148,7 @@ static void vb2_dc_put(void *buf_priv)
kfree(buf->sgt_base);
}
dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+   put_device(buf->dev);
kfree(buf);
 }

@@ -168,6 +169,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
return ERR_PTR(-ENOMEM);
}

+   /* prevent the device from release while the buffer is exported */
+   get_device(dev);
+
buf->dev = dev;
buf->size = size;

-- 
1.7.9.5



[PATCHv10 20/26] v4l: vb2-dma-contig: add support for DMABUF exporting

2012-10-10 Thread Tomasz Stanislawski
This patch adds support for exporting a dma-contig buffer using
DMABUF interface.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  200 
 1 file changed, 200 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 0e065ce..b138b5c 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -36,6 +36,7 @@ struct vb2_dc_buf {
/* MMAP related */
struct vb2_vmarea_handler   handler;
atomic_trefcount;
+   struct sg_table *sgt_base;

/* USERPTR related */
struct vm_area_struct   *vma;
@@ -142,6 +143,10 @@ static void vb2_dc_put(void *buf_priv)
if (!atomic_dec_and_test(>refcount))
return;

+   if (buf->sgt_base) {
+   sg_free_table(buf->sgt_base);
+   kfree(buf->sgt_base);
+   }
dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
kfree(buf);
 }
@@ -213,6 +218,200 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 }

 /*/
+/* DMABUF ops for exporters  */
+/*/
+
+struct vb2_dc_attachment {
+   struct sg_table sgt;
+   enum dma_data_direction dir;
+};
+
+static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
+   struct dma_buf_attachment *dbuf_attach)
+{
+   struct vb2_dc_attachment *attach;
+   unsigned int i;
+   struct scatterlist *rd, *wr;
+   struct sg_table *sgt;
+   struct vb2_dc_buf *buf = dbuf->priv;
+   int ret;
+
+   attach = kzalloc(sizeof(*attach), GFP_KERNEL);
+   if (!attach)
+   return -ENOMEM;
+
+   sgt = >sgt;
+   /* Copy the buf->base_sgt scatter list to the attachment, as we can't
+* map the same scatter list to multiple attachments at the same time.
+*/
+   ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
+   if (ret) {
+   kfree(attach);
+   return -ENOMEM;
+   }
+
+   rd = buf->sgt_base->sgl;
+   wr = sgt->sgl;
+   for (i = 0; i < sgt->orig_nents; ++i) {
+   sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
+   rd = sg_next(rd);
+   wr = sg_next(wr);
+   }
+
+   attach->dir = DMA_NONE;
+   dbuf_attach->priv = attach;
+
+   return 0;
+}
+
+static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
+   struct dma_buf_attachment *db_attach)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   struct sg_table *sgt;
+
+   if (!attach)
+   return;
+
+   sgt = >sgt;
+
+   /* release the scatterlist cache */
+   if (attach->dir != DMA_NONE)
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+   attach->dir);
+   sg_free_table(sgt);
+   kfree(attach);
+   db_attach->priv = NULL;
+}
+
+static struct sg_table *vb2_dc_dmabuf_ops_map(
+   struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   /* stealing dmabuf mutex to serialize map/unmap operations */
+   struct mutex *lock = _attach->dmabuf->lock;
+   struct sg_table *sgt;
+   int ret;
+
+   mutex_lock(lock);
+
+   sgt = >sgt;
+   /* return previously mapped sg table */
+   if (attach->dir == dir) {
+   mutex_unlock(lock);
+   return sgt;
+   }
+
+   /* release any previous cache */
+   if (attach->dir != DMA_NONE) {
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+   attach->dir);
+   attach->dir = DMA_NONE;
+   }
+
+   /* mapping to the client with new direction */
+   ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
+   if (ret <= 0) {
+   pr_err("failed to map scatterlist\n");
+   mutex_unlock(lock);
+   return ERR_PTR(-EIO);
+   }
+
+   attach->dir = dir;
+
+   mutex_unlock(lock);
+
+   return sgt;
+}
+
+static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
+   struct sg_table *sgt, enum dma_data_direction dir)
+{
+   /* nothing to be done here */
+}
+
+static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf)
+{
+   /* drop reference obtained in vb2_dc_get_dmabuf */
+   vb2_dc_put(dbuf->priv);
+}
+
+static void *vb2_dc_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum)
+{
+   struct vb2_dc_bu

[PATCHv10 19/26] v4l: vb2: add buffer exporting via dmabuf

2012-10-10 Thread Tomasz Stanislawski
This patch adds extension to videobuf2-core. It allow to export a mmap buffer
as a file descriptor.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c   |   13 +
 drivers/media/v4l2-core/videobuf2-core.c |   83 ++
 include/media/v4l2-mem2mem.h |3 ++
 include/media/videobuf2-core.h   |4 ++
 4 files changed, 103 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 3ac8358..9aa7cc7 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -369,6 +369,19 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx 
*m2m_ctx,
 EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);

 /**
+ * v4l2_m2m_expbuf() - export a source or destination buffer, depending on
+ * the type
+ */
+int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+ struct v4l2_exportbuffer *eb)
+{
+   struct vb2_queue *vq;
+
+   vq = v4l2_m2m_get_vq(m2m_ctx, eb->type);
+   return vb2_expbuf(vq, eb);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf);
+/**
  * v4l2_m2m_streamon() - turn on streaming for a video queue
  */
 int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 613dea1..9f81be2 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -1751,6 +1751,79 @@ static int __find_plane_by_offset(struct vb2_queue *q, 
unsigned long off,
 }

 /**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q: videobuf2 queue
+ * @eb:export buffer structure passed from userspace to 
vidioc_expbuf
+ * handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+   struct vb2_buffer *vb = NULL;
+   struct vb2_plane *vb_plane;
+   int ret;
+   struct dma_buf *dbuf;
+
+   if (q->memory != V4L2_MEMORY_MMAP) {
+   dprintk(1, "Queue is not currently set up for mmap\n");
+   return -EINVAL;
+   }
+
+   if (!q->mem_ops->get_dmabuf) {
+   dprintk(1, "Queue does not support DMA buffer exporting\n");
+   return -EINVAL;
+   }
+
+   if (eb->flags & ~O_CLOEXEC) {
+   dprintk(1, "Queue does support only O_CLOEXEC flag\n");
+   return -EINVAL;
+   }
+
+   if (eb->type != q->type) {
+   dprintk(1, "qbuf: invalid buffer type\n");
+   return -EINVAL;
+   }
+
+   if (eb->index >= q->num_buffers) {
+   dprintk(1, "buffer index out of range\n");
+   return -EINVAL;
+   }
+
+   vb = q->bufs[eb->index];
+
+   if (eb->plane >= vb->num_planes) {
+   dprintk(1, "buffer plane out of range\n");
+   return -EINVAL;
+   }
+
+   vb_plane = >planes[eb->plane];
+
+   dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+   if (IS_ERR_OR_NULL(dbuf)) {
+   dprintk(1, "Failed to export buffer %d, plane %d\n",
+   eb->index, eb->plane);
+   return -EINVAL;
+   }
+
+   ret = dma_buf_fd(dbuf, eb->flags);
+   if (ret < 0) {
+   dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
+   eb->index, eb->plane, ret);
+   dma_buf_put(dbuf);
+   return ret;
+   }
+
+   dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
+   eb->index, eb->plane, ret);
+   eb->fd = ret;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
+/**
  * vb2_mmap() - map video buffers into application address space
  * @q: videobuf2 queue
  * @vma:   vma passed to the mmap file operation handler in the driver
@@ -2456,6 +2529,16 @@ int vb2_ioctl_streamoff(struct file *file, void *priv, 
enum v4l2_buf_type i)
 }
 EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);

+int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer 
*p)
+{
+   struct video_device *vdev = video_devdata(file);
+
+   if (vb2_queue_is_busy(vdev, file))
+   return -EBUSY;
+   return vb2_expbuf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
+
 /* v4l2_file_operations helpers */

 int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 131cc4a..7e82d2b 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/includ

[PATCHv10 18/26] v4l: add buffer exporting via dmabuf

2012-10-10 Thread Tomasz Stanislawski
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file
descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by
mmap and return a file descriptor on success.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |1 +
 drivers/media/v4l2-core/v4l2-dev.c|1 +
 drivers/media/v4l2-core/v4l2-ioctl.c  |   10 +
 include/linux/videodev2.h |   28 +
 include/media/v4l2-ioctl.h|2 ++
 5 files changed, 42 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index cc5998b..7157af3 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -1018,6 +1018,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int 
cmd, unsigned long arg)
case VIDIOC_S_FBUF32:
case VIDIOC_OVERLAY32:
case VIDIOC_QBUF32:
+   case VIDIOC_EXPBUF:
case VIDIOC_DQBUF32:
case VIDIOC_STREAMON32:
case VIDIOC_STREAMOFF32:
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index a2df842..98dcad9 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -571,6 +571,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
+   SET_VALID_IOCTL(ops, VIDIOC_EXPBUF, vidioc_expbuf);
SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 530a67e..aa6e7c7 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -454,6 +454,15 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
tc->type, tc->flags, tc->frames, *(__u32 
*)tc->userbits);
 }

+static void v4l_print_exportbuffer(const void *arg, bool write_only)
+{
+   const struct v4l2_exportbuffer *p = arg;
+
+   pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
+   p->fd, prt_names(p->type, v4l2_type_names),
+   p->index, p->plane, p->flags);
+}
+
 static void v4l_print_create_buffers(const void *arg, bool write_only)
 {
const struct v4l2_create_buffers *p = arg;
@@ -1961,6 +1970,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, 
INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, 
INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
+   IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, 
INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, 
INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, 
INFO_FL_PRIO | INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, 
INFO_FL_PRIO | INFO_FL_QUEUE),
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 07bc5d6..19765df 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -696,6 +696,33 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE  0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN   0x1000

+/**
+ * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
+ *
+ * @index: id number of the buffer
+ * @type:  enum v4l2_buf_type; buffer type (type == *_MPLANE for
+ * multiplanar buffers);
+ * @plane: index of the plane to be exported, 0 for single plane queues
+ * @flags: flags for newly created file, currently only O_CLOEXEC is
+ * supported, refer to manual of open syscall for more details
+ * @fd:file descriptor associated with DMABUF (set by driver)
+ *
+ * Contains data used for exporting a video buffer as DMABUF file descriptor.
+ * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
+ * (identical to the cookie used to mmap() the buffer to userspace). All
+ * reserved fields must be set to zero. The field reserved0 is expected to
+ * become a structure 'type' allowing an alternative layout of the structure
+ * content. Therefore this field should not be used for any other extensions.
+ */
+struct v4l2_exportbuffer {
+   __u32   type; /* enum v4l2_buf_type */
+   __u32   index;
+   __u32   plane;
+   __u32   

[PATCHv10 17/26] Documentation: media: description of DMABUF exporting in V4L2

2012-10-10 Thread Tomasz Stanislawski
This patch adds description and usage examples for exporting
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: linux-doc at vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml|3 +
 Documentation/DocBook/media/v4l/io.xml|3 +
 Documentation/DocBook/media/v4l/v4l2.xml  |1 +
 Documentation/DocBook/media/v4l/vidioc-expbuf.xml |  212 +
 4 files changed, 219 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index 50eb630..3dd9e78 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2590,6 +2590,9 @@ ioctls.
  Importing DMABUF file descriptors as a new IO method described
  in .
 
+
+ Exporting DMABUF files using  ioctl.
+
   
 

diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index 0abb5cb..81d0ed4 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -488,6 +488,9 @@ DMA buffer from userspace using a file descriptor 
previously exported for a
 different or the same device (known as the importer role), or both. This
 section describes the DMABUF importer role API in V4L2.

+Refer to  DMABUF exporting  for
+details about exporting V4L2 buffers as DMABUF file descriptors.
+
 Input and output devices support the streaming I/O method when the
 V4L2_CAP_STREAMING flag in the
 capabilities field of  returned by
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml 
b/Documentation/DocBook/media/v4l/v4l2.xml
index 10ccde9..4d110b1 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -543,6 +543,7 @@ and discussions on the V4L mailing list.
 
 
 
+
 
 
 
diff --git a/Documentation/DocBook/media/v4l/vidioc-expbuf.xml 
b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
new file mode 100644
index 000..72dfbd2
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
@@ -0,0 +1,212 @@
+
+
+  
+ioctl VIDIOC_EXPBUF
+
+  
+
+  
+VIDIOC_EXPBUF
+Export a buffer as a DMABUF file descriptor.
+  
+
+  
+
+  
+   int ioctl
+   int fd
+   int request
+   struct v4l2_exportbuffer 
*argp
+  
+
+  
+
+  
+Arguments
+
+
+  
+   fd
+   
+ 
+   
+  
+  
+   request
+   
+ VIDIOC_EXPBUF
+   
+  
+  
+   argp
+   
+ 
+   
+  
+
+  
+
+  
+Description
+
+
+  Experimental
+  This is an  experimental 
+  interface and may change in the future.
+
+
+This ioctl is an extension to the memory
+mapping I/O method, therefore it is available only for
+V4L2_MEMORY_MMAP buffers.  It can be used to export a
+buffer as a DMABUF file at any time after buffers have been allocated with the
+ ioctl.
+
+ To export a buffer, applications fill .  The
+ type  field is set to the same buffer type as was
+previously used with   type .
+Applications must also set the  index  field. Valid
+index numbers range from zero to the number of buffers allocated with
+ ( count )
+minus one.  For the multi-planar API, applications set the  plane
+ field to the index of the plane to be exported. Valid planes
+range from zero to the maximal number of valid planes for the currently active
+format. For the single-planar API, applications must set  plane
+ to zero.  Additional flags may be posted in the 
+flags  field.  Refer to a manual for open() for details.
+Currently only O_CLOEXEC is supported.  All other fields must be set to zero.
+In the case of multi-planar API, every plane is exported separately using
+multiple  VIDIOC_EXPBUF  calls. 
+
+ After calling VIDIOC_EXPBUF the  fd
+ field will be set by a driver.  This is a DMABUF file
+descriptor. The application may pass it to other DMABUF-aware devices. Refer to
+DMABUF importing for details about importing
+DMABUF files into V4L2 nodes. It is recommended to close a DMABUF file when it
+is no longer used to allow the associated memory to be reclaimed. 
+
+  
+  
+   
+  Examples
+
+  
+   Exporting a buffer.
+   
+int buffer_export(int v4lfd,  bt, int index, int *dmafd)
+{
+expbuf;
+
+   memset(expbuf, 0, sizeof(expbuf));
+   expbuf.type = bt;
+   expbuf.index = index;
+   if (ioctl(v4lfd, , expbuf) == -1) {
+   perror("VIDIOC_EXPBUF");
+   return -1;
+   }
+
+   *dmafd = expbuf.fd;
+
+   return 0;
+}
+
+  
+
+  
+   Exporting a buffer using the multi-planar API.
+   
+int buffer_export_mp(int v4lfd,  bt, int index,
+   int dmafd[], int n_planes)
+{
+   int i;
+
+   for (i = 0; i  n_p

[PATCHv10 16/26] v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski <m.szyprow...@samsung.com>

Let mmap method to use dma_mmap_coherent call.  Moreover, this patch removes
vb2_mmap_pfn_range from videobuf2 helpers as it was suggested by Laurent
Pinchart.  The function is no longer used in vb2 code.

Signed-off-by: Marek Szyprowski 
Signed-off-by: Tomasz Stanislawski 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   28 +++--
 drivers/media/v4l2-core/videobuf2-memops.c |   40 
 include/media/videobuf2-memops.h   |5 ---
 3 files changed, 26 insertions(+), 47 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index a5804cf..0e065ce 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -178,14 +178,38 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
+   int ret;

if (!buf) {
printk(KERN_ERR "No buffer to map\n");
return -EINVAL;
}

-   return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size,
- _common_vm_ops, >handler);
+   /*
+* dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to
+* map whole buffer
+*/
+   vma->vm_pgoff = 0;
+
+   ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr,
+   buf->dma_addr, buf->size);
+
+   if (ret) {
+   pr_err("Remapping memory failed, error: %d\n", ret);
+   return ret;
+   }
+
+   vma->vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
+   vma->vm_private_data= >handler;
+   vma->vm_ops = _common_vm_ops;
+
+   vma->vm_ops->open(vma);
+
+   pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
+   __func__, (unsigned long)buf->dma_addr, vma->vm_start,
+   buf->size);
+
+   return 0;
 }

 /*/
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c 
b/drivers/media/v4l2-core/videobuf2-memops.c
index 504cd4c..81c1ad8 100644
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -137,46 +137,6 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned 
long size,
 EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);

 /**
- * vb2_mmap_pfn_range() - map physical pages to userspace
- * @vma:   virtual memory region for the mapping
- * @paddr: starting physical address of the memory to be mapped
- * @size:  size of the memory to be mapped
- * @vm_ops:vm operations to be assigned to the created area
- * @priv:  private data to be associated with the area
- *
- * Returns 0 on success.
- */
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv)
-{
-   int ret;
-
-   size = min_t(unsigned long, vma->vm_end - vma->vm_start, size);
-
-   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-   ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT,
-   size, vma->vm_page_prot);
-   if (ret) {
-   printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
-   return ret;
-   }
-
-   vma->vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
-   vma->vm_private_data= priv;
-   vma->vm_ops = vm_ops;
-
-   vma->vm_ops->open(vma);
-
-   pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
-   __func__, paddr, vma->vm_start, size);
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
-
-/**
  * vb2_common_vm_open() - increase refcount of the vma
  * @vma:   virtual memory region for the mapping
  *
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
index 84e1f6c..f05444c 100644
--- a/include/media/videobuf2-memops.h
+++ b/include/media/videobuf2-memops.h
@@ -33,11 +33,6 @@ extern const struct vm_operations_struct vb2_common_vm_ops;
 int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
   struct vm_area_struct **res_vma, dma_addr_t *res_pa);

-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv);
-
 struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
 void vb2_put_vma(struct vm_area_struct *vma);

-- 
1.7.9.5



[PATCHv10 15/26] v4l: s5p-fimc: support for dmabuf importing

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Sylwester Nawrocki 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-fimc/fimc-capture.c |2 +-
 drivers/media/platform/s5p-fimc/fimc-m2m.c |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c 
b/drivers/media/platform/s5p-fimc/fimc-capture.c
index 367efd1..246bb32 100644
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -1730,7 +1730,7 @@ static int fimc_register_capture_device(struct fimc_dev 
*fimc,
q = >vid_cap.vbq;
memset(q, 0, sizeof(*q));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
q->drv_priv = fimc->vid_cap.ctx;
q->ops = _capture_qops;
q->mem_ops = _dma_contig_memops;
diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c 
b/drivers/media/platform/s5p-fimc/fimc-m2m.c
index 4500e44..17067a7 100644
--- a/drivers/media/platform/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c
@@ -622,7 +622,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
int ret;

src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-   src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+   src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
src_vq->drv_priv = ctx;
src_vq->ops = _qops;
src_vq->mem_ops = _dma_contig_memops;
@@ -633,7 +633,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
return ret;

dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+   dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
dst_vq->drv_priv = ctx;
dst_vq->ops = _qops;
dst_vq->mem_ops = _dma_contig_memops;
-- 
1.7.9.5



[PATCHv10 14/26] v4l: s5p-tv: mixer: support for dmabuf importing

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-tv/mixer_video.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-tv/mixer_video.c 
b/drivers/media/platform/s5p-tv/mixer_video.c
index 0c1cd89..2421e527 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -1093,7 +1093,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device 
*mdev,

layer->vb_queue = (struct vb2_queue) {
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-   .io_modes = VB2_MMAP | VB2_USERPTR,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF,
.drv_priv = layer,
.buf_struct_size = sizeof(struct mxr_buffer),
.ops = _video_qops,
-- 
1.7.9.5



[PATCHv10 13/26] v4l: vivi: support for dmabuf importing

2012-10-10 Thread Tomasz Stanislawski
This patch enhances VIVI driver with a support for importing a buffer
from DMABUF file descriptors.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/vivi.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vivi.c b/drivers/media/platform/vivi.c
index b366b05..9e077bb 100644
--- a/drivers/media/platform/vivi.c
+++ b/drivers/media/platform/vivi.c
@@ -1308,7 +1308,7 @@ static int __init vivi_create_instance(int inst)
/* initialize queue */
q = >vb_vidq;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivi_buffer);
q->ops = _video_qops;
-- 
1.7.9.5



[PATCHv10 12/26] v4l: vb2-vmalloc: add support for dmabuf importing

2012-10-10 Thread Tomasz Stanislawski
This patch adds support for importing DMABUF files for
vmalloc allocator in Videobuf2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/Kconfig |1 +
 drivers/media/v4l2-core/videobuf2-vmalloc.c |   56 +++
 2 files changed, 57 insertions(+)

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index e30583b..65875c3 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -75,6 +75,7 @@ config VIDEOBUF2_VMALLOC
tristate
select VIDEOBUF2_CORE
select VIDEOBUF2_MEMOPS
+   select DMA_SHARED_BUFFER

 config VIDEOBUF2_DMA_SG
tristate
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c 
b/drivers/media/v4l2-core/videobuf2-vmalloc.c
index 94efa04..a47fd4f 100644
--- a/drivers/media/v4l2-core/videobuf2-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c
@@ -30,6 +30,7 @@ struct vb2_vmalloc_buf {
unsigned intn_pages;
atomic_trefcount;
struct vb2_vmarea_handler   handler;
+   struct dma_buf  *dbuf;
 };

 static void vb2_vmalloc_put(void *buf_priv);
@@ -207,11 +208,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
return 0;
 }

+/*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_vmalloc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   buf->vaddr = dma_buf_vmap(buf->dbuf);
+
+   return buf->vaddr ? 0 : -EFAULT;
+}
+
+static void vb2_vmalloc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   dma_buf_vunmap(buf->dbuf, buf->vaddr);
+   buf->vaddr = NULL;
+}
+
+static void vb2_vmalloc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   if (buf->vaddr)
+   dma_buf_vunmap(buf->dbuf, buf->vaddr);
+
+   kfree(buf);
+}
+
+static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_vmalloc_buf *buf;
+
+   if (dbuf->size < size)
+   return ERR_PTR(-EFAULT);
+
+   buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+   if (!buf)
+   return ERR_PTR(-ENOMEM);
+
+   buf->dbuf = dbuf;
+   buf->write = write;
+   buf->size = size;
+
+   return buf;
+}
+
+
 const struct vb2_mem_ops vb2_vmalloc_memops = {
.alloc  = vb2_vmalloc_alloc,
.put= vb2_vmalloc_put,
.get_userptr= vb2_vmalloc_get_userptr,
.put_userptr= vb2_vmalloc_put_userptr,
+   .map_dmabuf = vb2_vmalloc_map_dmabuf,
+   .unmap_dmabuf   = vb2_vmalloc_unmap_dmabuf,
+   .attach_dmabuf  = vb2_vmalloc_attach_dmabuf,
+   .detach_dmabuf  = vb2_vmalloc_detach_dmabuf,
.vaddr  = vb2_vmalloc_vaddr,
.mmap   = vb2_vmalloc_mmap,
.num_users  = vb2_vmalloc_num_users,
-- 
1.7.9.5



[PATCHv10 11/26] v4l: vb2-dma-contig: add support for dma_buf importing

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal <sumit.sem...@ti.com>

This patch makes changes for adding dma-contig as a dma_buf user. It provides
function implementations for the {attach, detach, map, unmap}_dmabuf()
mem_ops of DMABUF memory type.

Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
[author of the original patch]
Signed-off-by: Tomasz Stanislawski 
[integration with refactored dma-contig allocator]
Acked-by: Laurent Pinchart 
---
 drivers/media/v4l2-core/Kconfig|1 +
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  120 +++-
 2 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 2e787cc..e30583b 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -69,6 +69,7 @@ config VIDEOBUF2_DMA_CONTIG
tristate
select VIDEOBUF2_CORE
select VIDEOBUF2_MEMOPS
+   select DMA_SHARED_BUFFER

 config VIDEOBUF2_VMALLOC
tristate
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 494a824..a5804cf 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  */

+#include 
 #include 
 #include 
 #include 
@@ -38,6 +39,9 @@ struct vb2_dc_buf {

/* USERPTR related */
struct vm_area_struct   *vma;
+
+   /* DMABUF related */
+   struct dma_buf_attachment   *db_attach;
 };

 /*/
@@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;

-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf->db_attach)
return;

dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;

-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf->db_attach)
return;

dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -377,6 +383,112 @@ fail_buf:
 }

 /*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_dc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt;
+   unsigned long contig_size;
+
+   if (WARN_ON(!buf->db_attach)) {
+   pr_err("trying to pin a non attached buffer\n");
+   return -EINVAL;
+   }
+
+   if (WARN_ON(buf->dma_sgt)) {
+   pr_err("dmabuf buffer is already pinned\n");
+   return 0;
+   }
+
+   /* get the associated scatterlist for this buffer */
+   sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
+   if (IS_ERR_OR_NULL(sgt)) {
+   pr_err("Error getting dmabuf scatterlist\n");
+   return -EINVAL;
+   }
+
+   /* checking if dmabuf is big enough to store contiguous chunk */
+   contig_size = vb2_dc_get_contiguous_size(sgt);
+   if (contig_size < buf->size) {
+   pr_err("contiguous chunk is too small %lu/%lu b\n",
+   contig_size, buf->size);
+   dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+   return -EFAULT;
+   }
+
+   buf->dma_addr = sg_dma_address(sgt->sgl);
+   buf->dma_sgt = sgt;
+
+   return 0;
+}
+
+static void vb2_dc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (WARN_ON(!buf->db_attach)) {
+   pr_err("trying to unpin a not attached buffer\n");
+   return;
+   }
+
+   if (WARN_ON(!sgt)) {
+   pr_err("dmabuf buffer is already unpinned\n");
+   return;
+   }
+
+   dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+
+   buf->dma_addr = 0;
+   buf->dma_sgt = NULL;
+}
+
+static void vb2_dc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+
+   /* if vb2 works correctly you should never detach mapped buffer */
+   if (WARN_ON(buf->dma_addr))
+   vb2_dc_unmap_dmabuf(buf);
+
+   /* detach this attachment */
+   dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
+   kfree(buf);
+}
+
+static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_dc

[PATCHv10 10/26] v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Add prepare/finish callbacks to vb2-dma-contig allocator.

Signed-off-by: Marek Szyprowski 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 8486e06..494a824 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -103,6 +103,28 @@ static unsigned int vb2_dc_num_users(void *buf_priv)
return atomic_read(>refcount);
 }

+static void vb2_dc_prepare(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
+static void vb2_dc_finish(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
 /*/
 /*callbacks for MMAP buffers */
 /*/
@@ -366,6 +388,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = {
.mmap   = vb2_dc_mmap,
.get_userptr= vb2_dc_get_userptr,
.put_userptr= vb2_dc_put_userptr,
+   .prepare= vb2_dc_prepare,
+   .finish = vb2_dc_finish,
.num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
-- 
1.7.9.5



[PATCHv10 09/26] v4l: vb2: add prepare/finish callbacks to allocators

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski 

This patch adds support for prepare/finish callbacks in VB2 allocators. These
callback are used for buffer flushing.

Signed-off-by: Marek Szyprowski 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-core.c |   11 +++
 include/media/videobuf2-core.h   |7 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index a51dad6..613dea1 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -844,6 +844,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
 {
struct vb2_queue *q = vb->vb2_queue;
unsigned long flags;
+   unsigned int plane;

if (vb->state != VB2_BUF_STATE_ACTIVE)
return;
@@ -854,6 +855,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
dprintk(4, "Done processing on buffer %d, state: %d\n",
vb->v4l2_buf.index, vb->state);

+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_memop(q, finish, vb->planes[plane].mem_priv);
+
/* Add the buffer to the done buffers list */
spin_lock_irqsave(>done_lock, flags);
vb->state = state;
@@ -1136,9 +1141,15 @@ err:
 static void __enqueue_in_driver(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;

vb->state = VB2_BUF_STATE_ACTIVE;
atomic_inc(>queued_count);
+
+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_memop(q, prepare, vb->planes[plane].mem_priv);
+
q->ops->buf_queue(vb);
 }

diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 689ae4a..24b9c90 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -56,6 +56,10 @@ struct vb2_fileio_data;
  * dmabuf
  * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
  *   that this driver is done using the dmabuf for now
+ * @prepare:   called every time the buffer is passed from userspace to the
+ * driver, useful for cache synchronisation, optional
+ * @finish:called every time the buffer is passed back from the driver
+ * to the userspace, also optional
  * @vaddr: return a kernel virtual address to a given memory buffer
  * associated with the passed private structure or NULL if no
  * such mapping exists
@@ -82,6 +86,9 @@ struct vb2_mem_ops {
unsigned long size, int write);
void(*put_userptr)(void *buf_priv);

+   void(*prepare)(void *buf_priv);
+   void(*finish)(void *buf_priv);
+
void*(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf,
unsigned long size, int write);
void(*detach_dmabuf)(void *buf_priv);
-- 
1.7.9.5



[PATCHv10 08/26] v4l: vb2-dma-contig: add support for scatterlist in userptr mode

2012-10-10 Thread Tomasz Stanislawski
This patch introduces usage of dma_map_sg to map memory behind
a userspace pointer to a device as dma-contiguous mapping.

This patch contains some of the code kindly provided by Marek Szyprowski
 and Kamil Debski  and 
Andrzej
Pietrasiewicz . Kind thanks for bug reports from 
Laurent
Pinchart  and Seung-Woo Kim
.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  226 ++--
 1 file changed, 210 insertions(+), 16 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index daac2b2..8486e06 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -11,6 +11,8 @@
  */

 #include 
+#include 
+#include 
 #include 
 #include 

@@ -27,6 +29,8 @@ struct vb2_dc_buf {
void*vaddr;
unsigned long   size;
dma_addr_t  dma_addr;
+   enum dma_data_direction dma_dir;
+   struct sg_table *dma_sgt;

/* MMAP related */
struct vb2_vmarea_handler   handler;
@@ -37,6 +41,44 @@ struct vb2_dc_buf {
 };

 /*/
+/*scatterlist table functions*/
+/*/
+
+
+static void vb2_dc_sgt_foreach_page(struct sg_table *sgt,
+   void (*cb)(struct page *pg))
+{
+   struct scatterlist *s;
+   unsigned int i;
+
+   for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+   struct page *page = sg_page(s);
+   unsigned int n_pages = PAGE_ALIGN(s->offset + s->length)
+   >> PAGE_SHIFT;
+   unsigned int j;
+
+   for (j = 0; j < n_pages; ++j, ++page)
+   cb(page);
+   }
+}
+
+static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt)
+{
+   struct scatterlist *s;
+   dma_addr_t expected = sg_dma_address(sgt->sgl);
+   unsigned int i;
+   unsigned long size = 0;
+
+   for_each_sg(sgt->sgl, s, sgt->nents, i) {
+   if (sg_dma_address(s) != expected)
+   break;
+   expected = sg_dma_address(s) + sg_dma_len(s);
+   size += sg_dma_len(s);
+   }
+   return size;
+}
+
+/*/
 /* callbacks for all buffers */
 /*/

@@ -122,42 +164,194 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 /*   callbacks for USERPTR buffers   */
 /*/

+static inline int vma_is_io(struct vm_area_struct *vma)
+{
+   return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
+}
+
+static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+   int n_pages, struct vm_area_struct *vma, int write)
+{
+   if (vma_is_io(vma)) {
+   unsigned int i;
+
+   for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) {
+   unsigned long pfn;
+   int ret = follow_pfn(vma, start, );
+
+   if (ret) {
+   pr_err("no page for address %lu\n", start);
+   return ret;
+   }
+   pages[i] = pfn_to_page(pfn);
+   }
+   } else {
+   int n;
+
+   n = get_user_pages(current, current->mm, start & PAGE_MASK,
+   n_pages, write, 1, pages, NULL);
+   /* negative error means that no page was pinned */
+   n = max(n, 0);
+   if (n != n_pages) {
+   pr_err("got only %d of %d user pages\n", n, n_pages);
+   while (n)
+   put_page(pages[--n]);
+   return -EFAULT;
+   }
+   }
+
+   return 0;
+}
+
+static void vb2_dc_put_dirty_page(struct page *page)
+{
+   set_page_dirty_lock(page);
+   put_page(page);
+}
+
+static void vb2_dc_put_userptr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+   if (!vma_is_io(buf->vma))
+   vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
+
+   sg_free_table(sgt);
+   kfree(sgt);
+   vb2_put_vma(buf->vma);
+   kfree(buf);
+}
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
-   unsigned long size, int write)
+   unsigned long size, int write)
 {
+   struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *b

[PATCHv10 07/26] v4l: vb2-dma-contig: reorder functions

2012-10-10 Thread Tomasz Stanislawski
From: Laurent Pinchart 

Group functions by buffer type.

Signed-off-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   92 ++--
 1 file changed, 54 insertions(+), 38 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 20c95da..daac2b2 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -25,14 +25,56 @@ struct vb2_dc_conf {
 struct vb2_dc_buf {
struct device   *dev;
void*vaddr;
-   dma_addr_t  dma_addr;
unsigned long   size;
-   struct vm_area_struct   *vma;
-   atomic_trefcount;
+   dma_addr_t  dma_addr;
+
+   /* MMAP related */
struct vb2_vmarea_handler   handler;
+   atomic_trefcount;
+
+   /* USERPTR related */
+   struct vm_area_struct   *vma;
 };

-static void vb2_dc_put(void *buf_priv);
+/*/
+/* callbacks for all buffers */
+/*/
+
+static void *vb2_dc_cookie(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return >dma_addr;
+}
+
+static void *vb2_dc_vaddr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return buf->vaddr;
+}
+
+static unsigned int vb2_dc_num_users(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return atomic_read(>refcount);
+}
+
+/*/
+/*callbacks for MMAP buffers */
+/*/
+
+static void vb2_dc_put(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   if (!atomic_dec_and_test(>refcount))
+   return;
+
+   dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+   kfree(buf);
+}

 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
@@ -63,40 +105,6 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
return buf;
 }

-static void vb2_dc_put(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   if (atomic_dec_and_test(>refcount)) {
-   dma_free_coherent(buf->dev, buf->size, buf->vaddr,
- buf->dma_addr);
-   kfree(buf);
-   }
-}
-
-static void *vb2_dc_cookie(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return >dma_addr;
-}
-
-static void *vb2_dc_vaddr(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-   if (!buf)
-   return NULL;
-
-   return buf->vaddr;
-}
-
-static unsigned int vb2_dc_num_users(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return atomic_read(>refcount);
-}
-
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
@@ -110,6 +118,10 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  _common_vm_ops, >handler);
 }

+/*/
+/*   callbacks for USERPTR buffers   */
+/*/
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
@@ -148,6 +160,10 @@ static void vb2_dc_put_userptr(void *mem_priv)
kfree(buf);
 }

+/*/
+/*   DMA CONTIG exported functions   */
+/*/
+
 const struct vb2_mem_ops vb2_dma_contig_memops = {
.alloc  = vb2_dc_alloc,
.put= vb2_dc_put,
-- 
1.7.9.5



[PATCHv10 06/26] v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer

2012-10-10 Thread Tomasz Stanislawski
This patch removes a reference to alloc_ctx from an instance of a DMA
contiguous buffer. It helps to avoid a risk of a dangling pointer if the
context is released while the buffer is still valid. Moreover it removes one
dereference step while accessing a device structure.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index a05784f..20c95da 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -23,7 +23,7 @@ struct vb2_dc_conf {
 };

 struct vb2_dc_buf {
-   struct vb2_dc_conf  *conf;
+   struct device   *dev;
void*vaddr;
dma_addr_t  dma_addr;
unsigned long   size;
@@ -37,22 +37,21 @@ static void vb2_dc_put(void *buf_priv);
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
+   struct device *dev = conf->dev;
struct vb2_dc_buf *buf;

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

-   buf->vaddr = dma_alloc_coherent(conf->dev, size, >dma_addr,
-   GFP_KERNEL);
+   buf->vaddr = dma_alloc_coherent(dev, size, >dma_addr, GFP_KERNEL);
if (!buf->vaddr) {
-   dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
-   size);
+   dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
kfree(buf);
return ERR_PTR(-ENOMEM);
}

-   buf->conf = conf;
+   buf->dev = dev;
buf->size = size;

buf->handler.refcount = >refcount;
@@ -69,7 +68,7 @@ static void vb2_dc_put(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;

if (atomic_dec_and_test(>refcount)) {
-   dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr,
+   dma_free_coherent(buf->dev, buf->size, buf->vaddr,
  buf->dma_addr);
kfree(buf);
}
-- 
1.7.9.5



[PATCHv10 05/26] v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc

2012-10-10 Thread Tomasz Stanislawski
From: Laurent Pinchart 

Signed-off-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   36 
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 4b71326..a05784f 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -32,9 +32,9 @@ struct vb2_dc_buf {
struct vb2_vmarea_handler   handler;
 };

-static void vb2_dma_contig_put(void *buf_priv);
+static void vb2_dc_put(void *buf_priv);

-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
+static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
@@ -56,7 +56,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
buf->size = size;

buf->handler.refcount = >refcount;
-   buf->handler.put = vb2_dma_contig_put;
+   buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;

atomic_inc(>refcount);
@@ -64,7 +64,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
return buf;
 }

-static void vb2_dma_contig_put(void *buf_priv)
+static void vb2_dc_put(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;

@@ -75,14 +75,14 @@ static void vb2_dma_contig_put(void *buf_priv)
}
 }

-static void *vb2_dma_contig_cookie(void *buf_priv)
+static void *vb2_dc_cookie(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;

return >dma_addr;
 }

-static void *vb2_dma_contig_vaddr(void *buf_priv)
+static void *vb2_dc_vaddr(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
if (!buf)
@@ -91,14 +91,14 @@ static void *vb2_dma_contig_vaddr(void *buf_priv)
return buf->vaddr;
 }

-static unsigned int vb2_dma_contig_num_users(void *buf_priv)
+static unsigned int vb2_dc_num_users(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;

return atomic_read(>refcount);
 }

-static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
+static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;

@@ -111,7 +111,7 @@ static int vb2_dma_contig_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  _common_vm_ops, >handler);
 }

-static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
struct vb2_dc_buf *buf;
@@ -138,7 +138,7 @@ static void *vb2_dma_contig_get_userptr(void *alloc_ctx, 
unsigned long vaddr,
return buf;
 }

-static void vb2_dma_contig_put_userptr(void *mem_priv)
+static void vb2_dc_put_userptr(void *mem_priv)
 {
struct vb2_dc_buf *buf = mem_priv;

@@ -150,14 +150,14 @@ static void vb2_dma_contig_put_userptr(void *mem_priv)
 }

 const struct vb2_mem_ops vb2_dma_contig_memops = {
-   .alloc  = vb2_dma_contig_alloc,
-   .put= vb2_dma_contig_put,
-   .cookie = vb2_dma_contig_cookie,
-   .vaddr  = vb2_dma_contig_vaddr,
-   .mmap   = vb2_dma_contig_mmap,
-   .get_userptr= vb2_dma_contig_get_userptr,
-   .put_userptr= vb2_dma_contig_put_userptr,
-   .num_users  = vb2_dma_contig_num_users,
+   .alloc  = vb2_dc_alloc,
+   .put= vb2_dc_put,
+   .cookie = vb2_dc_cookie,
+   .vaddr  = vb2_dc_vaddr,
+   .mmap   = vb2_dc_mmap,
+   .get_userptr= vb2_dc_get_userptr,
+   .put_userptr= vb2_dc_put_userptr,
+   .num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);

-- 
1.7.9.5



[PATCHv10 04/26] v4l: vb: remove warnings about MEMORY_DMABUF

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal 

Adding DMABUF memory type causes videobuf to complain about not using it
in some switch cases. This patch removes these warnings.

Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf-core.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf-core.c 
b/drivers/media/v4l2-core/videobuf-core.c
index bf7a326..5449e8a 100644
--- a/drivers/media/v4l2-core/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
@@ -335,6 +335,9 @@ static void videobuf_status(struct videobuf_queue *q, 
struct v4l2_buffer *b,
case V4L2_MEMORY_OVERLAY:
b->m.offset  = vb->boff;
break;
+   case V4L2_MEMORY_DMABUF:
+   /* DMABUF is not handled in videobuf framework */
+   break;
}

b->flags= 0;
@@ -405,6 +408,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
break;
case V4L2_MEMORY_USERPTR:
case V4L2_MEMORY_OVERLAY:
+   case V4L2_MEMORY_DMABUF:
/* nothing */
break;
}
-- 
1.7.9.5



[PATCHv10 03/26] v4l: vb2: add support for shared buffer (dma_buf)

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal <sumit.sem...@ti.com>

This patch adds support for DMABUF memory type in videobuf2. It calls relevant
APIs of dma_buf for v4l reqbuf / qbuf / dqbuf operations.

For this version, the support is for videobuf2 as a user of the shared buffer;
so the allocation of the buffer is done outside of V4L2. [A sample allocator of
dma-buf shared buffer is given at [1]]

[1]: Rob Clark's DRM:
   https://github.com/robclark/kernel-omap4/commits/drmplane-dmabuf

Signed-off-by: Tomasz Stanislawski 
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/Kconfig  |1 +
 drivers/media/v4l2-core/videobuf2-core.c |  206 +-
 include/media/videobuf2-core.h   |   27 
 3 files changed, 231 insertions(+), 3 deletions(-)

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 0c54e19..2e787cc 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -59,6 +59,7 @@ config VIDEOBUF_DVB

 # Used by drivers that need Videobuf2 modules
 config VIDEOBUF2_CORE
+   select DMA_SHARED_BUFFER
tristate

 config VIDEOBUF2_MEMOPS
diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 432df11..a51dad6 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -109,6 +109,36 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
 }

 /**
+ * __vb2_plane_dmabuf_put() - release memory associated with
+ * a DMABUF shared plane
+ */
+static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
+{
+   if (!p->mem_priv)
+   return;
+
+   if (p->dbuf_mapped)
+   call_memop(q, unmap_dmabuf, p->mem_priv);
+
+   call_memop(q, detach_dmabuf, p->mem_priv);
+   dma_buf_put(p->dbuf);
+   memset(p, 0, sizeof(*p));
+}
+
+/**
+ * __vb2_buf_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
+{
+   struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;
+
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   __vb2_plane_dmabuf_put(q, >planes[plane]);
+}
+
+/**
  * __setup_offsets() - setup unique offsets ("cookies") for every plane in
  * every buffer on the queue
  */
@@ -230,6 +260,8 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned 
int buffers)
/* Free MMAP buffers or release USERPTR buffers */
if (q->memory == V4L2_MEMORY_MMAP)
__vb2_buf_mem_free(vb);
+   else if (q->memory == V4L2_MEMORY_DMABUF)
+   __vb2_buf_dmabuf_put(vb);
else
__vb2_buf_userptr_put(vb);
}
@@ -362,6 +394,8 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, 
struct v4l2_buffer *b)
b->m.offset = vb->v4l2_planes[0].m.mem_offset;
else if (q->memory == V4L2_MEMORY_USERPTR)
b->m.userptr = vb->v4l2_planes[0].m.userptr;
+   else if (q->memory == V4L2_MEMORY_DMABUF)
+   b->m.fd = vb->v4l2_planes[0].m.fd;
}

/*
@@ -454,13 +488,28 @@ static int __verify_mmap_ops(struct vb2_queue *q)
 }

 /**
+ * __verify_dmabuf_ops() - verify that all memory operations required for
+ * DMABUF queue type have been provided
+ */
+static int __verify_dmabuf_ops(struct vb2_queue *q)
+{
+   if (!(q->io_modes & VB2_DMABUF) || !q->mem_ops->attach_dmabuf ||
+   !q->mem_ops->detach_dmabuf  || !q->mem_ops->map_dmabuf ||
+   !q->mem_ops->unmap_dmabuf)
+   return -EINVAL;
+
+   return 0;
+}
+
+/**
  * __verify_memory_type() - Check whether the memory type and buffer type
  * passed to a buffer operation are compatible with the queue.
  */
 static int __verify_memory_type(struct vb2_queue *q,
enum v4l2_memory memory, enum v4l2_buf_type type)
 {
-   if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR) {
+   if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR &&
+   memory != V4L2_MEMORY_DMABUF) {
dprintk(1, "reqbufs: unsupported memory type\n");
return -EINVAL;
}
@@ -484,6 +533,11 @@ static int __verify_memory_type(struct vb2_queue *q,
return -EINVAL;
}

+   if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {
+   dprintk(1, "reqbufs: DMABUF for current setup unsupported\n");
+   return -EINVAL;
+   }
+
/*
 * Place the busy tests at the end: -EBUSY can be ignored when
 

[PATCHv10 02/26] Documentation: media: description of DMABUF importing in V4L2

2012-10-10 Thread Tomasz Stanislawski
This patch adds description and usage examples for importing
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: linux-doc at vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml |4 +
 Documentation/DocBook/media/v4l/io.xml |  181 +++-
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |   16 +-
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   17 ++
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 ++---
 5 files changed, 235 insertions(+), 30 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index 4fdf6b5..50eb630 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2586,6 +2586,10 @@ ioctls.
  Vendor and device specific media bus pixel formats.
.
 
+
+ Importing DMABUF file descriptors as a new IO method described
+ in .
+
   
 

diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index b5d1cbd..0abb5cb 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -331,7 +331,7 @@ application until one or more buffers can be dequeued. By 
default
 outgoing queue. When the O_NONBLOCK flag was
 given to the  function, VIDIOC_DQBUF
 returns immediately with an  when no buffer is available. The
- or  function are always available.
+ or  functions are always available.

 To start and stop capturing or output applications call the
  and  ioctl. Note
@@ -472,6 +472,162 @@ rest should be evident.
   
   

+  
+Streaming I/O (DMA buffer importing)
+
+
+  Experimental
+  This is an  experimental 
+  interface and may change in the future.
+
+
+The DMABUF framework provides a generic method for sharing buffers
+between multiple devices. Device drivers that support DMABUF can export a DMA
+buffer to userspace as a file descriptor (known as the exporter role), import a
+DMA buffer from userspace using a file descriptor previously exported for a
+different or the same device (known as the importer role), or both. This
+section describes the DMABUF importer role API in V4L2.
+
+Input and output devices support the streaming I/O method when the
+V4L2_CAP_STREAMING flag in the
+capabilities field of  returned by
+the  ioctl is set. Whether importing DMA buffers through
+DMABUF file descriptors is supported is determined by calling the
+ ioctl with the memory type set to
+V4L2_MEMORY_DMABUF.
+
+This I/O method is dedicated to sharing DMA buffers between different
+devices, which may be V4L devices or other video-related devices (e.g. DRM).
+Buffers (planes) are allocated by a driver on behalf of an application. Next,
+these buffers are exported to the application as file descriptors using an API
+which is specific for an allocator driver.  Only such file descriptor are
+exchanged. The descriptors and meta-information are passed in  (or
+in  in the multi-planar API case).  The driver must be switched
+into DMABUF I/O mode by calling the  with the desired buffer
+type.
+
+
+  Initiating streaming I/O with DMABUF file descriptors
+
+  
+ reqbuf;
+
+memset(reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_DMABUF;
+reqbuf.count = 1;
+
+if (ioctl(fd, , reqbuf) == -1) {
+   if (errno == EINVAL)
+   printf("Video capturing or DMABUF streaming is not 
supported\n");
+   else
+   perror("VIDIOC_REQBUFS");
+
+   exit(EXIT_FAILURE);
+}
+  
+
+
+The buffer (plane) file descriptor is passed on the fly with the
+ ioctl. In case of multiplanar buffers, every plane can be
+associated with a different DMABUF descriptor. Although buffers are commonly
+cycled, applications can pass a different DMABUF descriptor at each
+VIDIOC_QBUF call.
+
+
+  Queueing DMABUF using single plane API
+
+  
+int buffer_queue(int v4lfd, int index, int dmafd)
+{
+buf;
+
+   memset(buf, 0, sizeof buf);
+   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+   buf.memory = V4L2_MEMORY_DMABUF;
+   buf.index = index;
+   buf.m.fd = dmafd;
+
+   if (ioctl(v4lfd, , buf) == -1) {
+   perror("VIDIOC_QBUF");
+   return -1;
+   }
+
+   return 0;
+}
+  
+
+
+
+  Queueing DMABUF using multi plane API
+
+  
+int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
+{
+buf;
+planes[VIDEO_MAX_PLANES];
+   int i;
+
+   memset(buf, 0, sizeof buf);
+   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+   buf.memory = V4L2_MEMORY_DMABUF;
+   buf.index = index;
+   buf.m.planes = planes;
+   buf.length = n_planes;
+
+   memset(planes, 0, sizeof planes);
+
+ 

[PATCHv10 01/26] v4l: Add DMABUF as a memory type

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal <sumit.sem...@ti.com>

Adds DMABUF memory type to v4l framework. Also adds the related file
descriptor in v4l2_plane and v4l2_buffer.

Signed-off-by: Tomasz Stanislawski 
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |   18 ++
 drivers/media/v4l2-core/v4l2-ioctl.c  |1 +
 include/linux/videodev2.h |7 +++
 3 files changed, 26 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 83ffb64..cc5998b 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -297,6 +297,7 @@ struct v4l2_plane32 {
union {
__u32   mem_offset;
compat_long_t   userptr;
+   __s32   fd;
} m;
__u32   data_offset;
__u32   reserved[11];
@@ -318,6 +319,7 @@ struct v4l2_buffer32 {
__u32   offset;
compat_long_t   userptr;
compat_caddr_t  planes;
+   __s32   fd;
} m;
__u32   length;
__u32   reserved2;
@@ -341,6 +343,9 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
up_pln = compat_ptr(p);
if (put_user((unsigned long)up_pln, >m.userptr))
return -EFAULT;
+   } else if (memory == V4L2_MEMORY_DMABUF) {
+   if (copy_in_user(>m.fd, >m.fd, sizeof(int)))
+   return -EFAULT;
} else {
if (copy_in_user(>m.mem_offset, >m.mem_offset,
sizeof(__u32)))
@@ -364,6 +369,11 @@ static int put_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
if (copy_in_user(>m.mem_offset, >m.mem_offset,
sizeof(__u32)))
return -EFAULT;
+   /* For DMABUF, driver might've set up the fd, so copy it back. */
+   if (memory == V4L2_MEMORY_DMABUF)
+   if (copy_in_user(>m.fd, >m.fd,
+   sizeof(int)))
+   return -EFAULT;

return 0;
 }
@@ -446,6 +456,10 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (get_user(kp->m.offset, >m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (get_user(kp->m.fd, >m.fd))
+   return -EFAULT;
+   break;
}
}

@@ -510,6 +524,10 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (put_user(kp->m.offset, >m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (put_user(kp->m.fd, >m.fd))
+   return -EFAULT;
+   break;
}
}

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 8f388ff..530a67e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -155,6 +155,7 @@ static const char *v4l2_memory_names[] = {
[V4L2_MEMORY_MMAP]= "mmap",
[V4L2_MEMORY_USERPTR] = "userptr",
[V4L2_MEMORY_OVERLAY] = "overlay",
+   [V4L2_MEMORY_DMABUF] = "dmabuf",
 };

 #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : 
"unknown")
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 873adbe..07bc5d6 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -188,6 +188,7 @@ enum v4l2_memory {
V4L2_MEMORY_MMAP = 1,
V4L2_MEMORY_USERPTR  = 2,
V4L2_MEMORY_OVERLAY  = 3,
+   V4L2_MEMORY_DMABUF   = 4,
 };

 /* see also http://vektor.theorem.ca/graphics/ycbcr/ */
@@ -604,6 +605,8 @@ struct v4l2_requestbuffers {
  * should be passed to mmap() called on the video node)
  * @userptr:   when memory is V4L2_MEMORY_USERPTR, a userspace pointer
  * pointing to this plane
+ * @fd:when memory is V4L2_MEMORY_DMABUF, a userspace 
file
+ * descriptor associated with this plane
  * @data_offset:   offset in the plane to the start of data; usually 0,
  * unless there is a header in front of t

[PATCHv10 00/26] Integration of videobuf2 with DMABUF

2012-10-10 Thread Tomasz Stanislawski
] http://thread.gmane.org/gmane.linux.kernel.cross-arch/12819
[4] 
http://article.gmane.org/gmane.linux.drivers.video-input-infrastructure/49700

Laurent Pinchart (2):
  v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc
  v4l: vb2-dma-contig: reorder functions

Marek Szyprowski (4):
  v4l: vb2: add prepare/finish callbacks to allocators
  v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator
  v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call
  v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

Sumit Semwal (4):
  v4l: Add DMABUF as a memory type
  v4l: vb2: add support for shared buffer (dma_buf)
  v4l: vb: remove warnings about MEMORY_DMABUF
  v4l: vb2-dma-contig: add support for dma_buf importing

Tomasz Stanislawski (16):
  Documentation: media: description of DMABUF importing in V4L2
  v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer
  v4l: vb2-dma-contig: add support for scatterlist in userptr mode
  v4l: vb2-vmalloc: add support for dmabuf importing
  v4l: vivi: support for dmabuf importing
  v4l: s5p-tv: mixer: support for dmabuf importing
  v4l: s5p-fimc: support for dmabuf importing
  Documentation: media: description of DMABUF exporting in V4L2
  v4l: add buffer exporting via dmabuf
  v4l: vb2: add buffer exporting via dmabuf
  v4l: vb2-dma-contig: add support for DMABUF exporting
  v4l: vb2-dma-contig: add reference counting for a device from
allocator context
  v4l: vb2-dma-contig: align buffer size to PAGE_SIZE
  v4l: s5p-fimc: support for dmabuf exporting
  v4l: s5p-tv: mixer: support for dmabuf exporting
  v4l: s5p-mfc: support for dmabuf exporting

 Documentation/DocBook/media/v4l/compat.xml |7 +
 Documentation/DocBook/media/v4l/io.xml |  184 -
 Documentation/DocBook/media/v4l/v4l2.xml   |1 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |   16 +-
 Documentation/DocBook/media/v4l/vidioc-expbuf.xml  |  212 ++
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   17 +
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 +-
 drivers/media/platform/s5p-fimc/fimc-capture.c |   11 +-
 drivers/media/platform/s5p-fimc/fimc-m2m.c |   14 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_dec.c   |   14 +
 drivers/media/platform/s5p-mfc/s5p_mfc_enc.c   |   14 +
 drivers/media/platform/s5p-tv/mixer_video.c|   12 +-
 drivers/media/platform/vivi.c  |2 +-
 drivers/media/v4l2-core/Kconfig|3 +
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c  |   19 +
 drivers/media/v4l2-core/v4l2-dev.c |1 +
 drivers/media/v4l2-core/v4l2-ioctl.c   |   11 +
 drivers/media/v4l2-core/v4l2-mem2mem.c |   13 +
 drivers/media/v4l2-core/videobuf-core.c|4 +
 drivers/media/v4l2-core/videobuf2-core.c   |  300 -
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  702 ++--
 drivers/media/v4l2-core/videobuf2-memops.c |   40 --
 drivers/media/v4l2-core/videobuf2-vmalloc.c|   56 ++
 include/linux/videodev2.h  |   35 +
 include/media/v4l2-ioctl.h |2 +
 include/media/v4l2-mem2mem.h   |3 +
 include/media/videobuf2-core.h |   38 ++
 include/media/videobuf2-memops.h   |5 -
 28 files changed, 1645 insertions(+), 138 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml

-- 
1.7.9.5



[PATCHv9 19/25] v4l: vb2: add buffer exporting via dmabuf

2012-10-10 Thread Tomasz Stanislawski
On 10/06/2012 02:22 PM, Hans Verkuil wrote:
> On Tue October 2 2012 16:27:30 Tomasz Stanislawski wrote:
>> This patch adds extension to videobuf2-core. It allow to export a mmap buffer
>> as a file descriptor.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> Signed-off-by: Kyungmin Park 
>> Acked-by: Laurent Pinchart 
>> ---
>>  drivers/media/video/videobuf2-core.c |   82 
>> ++
>>  include/media/videobuf2-core.h   |4 ++
>>  2 files changed, 86 insertions(+)
>>
>> diff --git a/drivers/media/video/videobuf2-core.c 
>> b/drivers/media/video/videobuf2-core.c
>> index 05da3b4..a97815b 100644
>> --- a/drivers/media/video/videobuf2-core.c
>> +++ b/drivers/media/video/videobuf2-core.c
> 
> 
> 
>> @@ -2455,6 +2528,15 @@ int vb2_ioctl_streamoff(struct file *file, void 
>> *priv, enum v4l2_buf_type i)
>>  }
>>  EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
>>  
>> +int vb2_ioctl_expbuf(struct file *file, void *priv, struct 
>> v4l2_exportbuffer *p)
>> +{
>> +struct video_device *vdev = video_devdata(file);
>> +
>> +/* No need to call vb2_queue_is_busy(), anyone can export buffers. */

Hi Hans,

> 
> After thinking about this some more I'm not so sure we should allow this.
> Exporting a buffer also means that the memory can't be freed as long as the
> exported filehandle remains open.
> 

You are completely right.
But the problem is much more complex ... see below.

> That means that it is possible to make a malicious application that exports
> the buffers and never frees them, which can cause havoc.

What kind of havoc do you mean? Resource leakage?

> I think that only
> the filehandle that called REQBUFS/CREATE_BUFS should be allowed to export
> buffers.

Notice that you should allow to call mmap() only for the file handles that 
called
REQBUFS/CREATE_BUFS. The mmap() creates a vma that holds a reference to a 
buffer.
As long as the mapping exists, the buffers cannot be freed and REQBUFS(count=0) 
returns -EBUSY.
According to V4L2 spec all the nodes share the same context, therefore
one process can call REQBUFS, and the other can call QUERYBUF and mmap().

Therefore if EXPBUF has to check vb2_queue_is_busy() then vb2_fop_mmap()
should do the same check too.

IMO, it is very difficult to develop a useful multi-client API that
would protect V4L2 from creating non-freeable buffers by a rogue applications.

I think that the requirements below:

- the buffers should be sharable between processes by mmap(), or DMABUF 
exporting
- the REQBUFS(count=0) should release the buffers

are contradictory and cannot be *reliably* satisfied at the same time.
Notice that REQBUFS(count=0) that unexpectedly return -EBUSY is not
a reliable solution. The application cannot do anything fix the problem
after receiving -EBUSY.

Anyway, I will apply the check for vb2_queue_is_busy() in v2b_ioctl_expbuf().

Regards,
Tomasz Stanislawski

> 
> What do you think?
> 
> Regards,
> 
>   Hans
> 
>> +return vb2_expbuf(vdev->queue, p);
>> +}
>> +EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
>> +
>>  /* v4l2_file_operations helpers */
>>  
>>  int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)



Re: [PATCHv9 19/25] v4l: vb2: add buffer exporting via dmabuf

2012-10-10 Thread Tomasz Stanislawski
On 10/06/2012 02:22 PM, Hans Verkuil wrote:
 On Tue October 2 2012 16:27:30 Tomasz Stanislawski wrote:
 This patch adds extension to videobuf2-core. It allow to export a mmap buffer
 as a file descriptor.

 Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
 ---
  drivers/media/video/videobuf2-core.c |   82 
 ++
  include/media/videobuf2-core.h   |4 ++
  2 files changed, 86 insertions(+)

 diff --git a/drivers/media/video/videobuf2-core.c 
 b/drivers/media/video/videobuf2-core.c
 index 05da3b4..a97815b 100644
 --- a/drivers/media/video/videobuf2-core.c
 +++ b/drivers/media/video/videobuf2-core.c
 
 snip
 
 @@ -2455,6 +2528,15 @@ int vb2_ioctl_streamoff(struct file *file, void 
 *priv, enum v4l2_buf_type i)
  }
  EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
  
 +int vb2_ioctl_expbuf(struct file *file, void *priv, struct 
 v4l2_exportbuffer *p)
 +{
 +struct video_device *vdev = video_devdata(file);
 +
 +/* No need to call vb2_queue_is_busy(), anyone can export buffers. */

Hi Hans,

 
 After thinking about this some more I'm not so sure we should allow this.
 Exporting a buffer also means that the memory can't be freed as long as the
 exported filehandle remains open.
 

You are completely right.
But the problem is much more complex ... see below.

 That means that it is possible to make a malicious application that exports
 the buffers and never frees them, which can cause havoc.

What kind of havoc do you mean? Resource leakage?

 I think that only
 the filehandle that called REQBUFS/CREATE_BUFS should be allowed to export
 buffers.

Notice that you should allow to call mmap() only for the file handles that 
called
REQBUFS/CREATE_BUFS. The mmap() creates a vma that holds a reference to a 
buffer.
As long as the mapping exists, the buffers cannot be freed and REQBUFS(count=0) 
returns -EBUSY.
According to V4L2 spec all the nodes share the same context, therefore
one process can call REQBUFS, and the other can call QUERYBUF and mmap().

Therefore if EXPBUF has to check vb2_queue_is_busy() then vb2_fop_mmap()
should do the same check too.

IMO, it is very difficult to develop a useful multi-client API that
would protect V4L2 from creating non-freeable buffers by a rogue applications.

I think that the requirements below:

- the buffers should be sharable between processes by mmap(), or DMABUF 
exporting
- the REQBUFS(count=0) should release the buffers

are contradictory and cannot be *reliably* satisfied at the same time.
Notice that REQBUFS(count=0) that unexpectedly return -EBUSY is not
a reliable solution. The application cannot do anything fix the problem
after receiving -EBUSY.

Anyway, I will apply the check for vb2_queue_is_busy() in v2b_ioctl_expbuf().

Regards,
Tomasz Stanislawski

 
 What do you think?
 
 Regards,
 
   Hans
 
 +return vb2_expbuf(vdev-queue, p);
 +}
 +EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
 +
  /* v4l2_file_operations helpers */
  
  int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 00/26] Integration of videobuf2 with DMABUF

2012-10-10 Thread Tomasz Stanislawski
] http://thread.gmane.org/gmane.linux.kernel.cross-arch/12819
[4] 
http://article.gmane.org/gmane.linux.drivers.video-input-infrastructure/49700

Laurent Pinchart (2):
  v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc
  v4l: vb2-dma-contig: reorder functions

Marek Szyprowski (4):
  v4l: vb2: add prepare/finish callbacks to allocators
  v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator
  v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call
  v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

Sumit Semwal (4):
  v4l: Add DMABUF as a memory type
  v4l: vb2: add support for shared buffer (dma_buf)
  v4l: vb: remove warnings about MEMORY_DMABUF
  v4l: vb2-dma-contig: add support for dma_buf importing

Tomasz Stanislawski (16):
  Documentation: media: description of DMABUF importing in V4L2
  v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer
  v4l: vb2-dma-contig: add support for scatterlist in userptr mode
  v4l: vb2-vmalloc: add support for dmabuf importing
  v4l: vivi: support for dmabuf importing
  v4l: s5p-tv: mixer: support for dmabuf importing
  v4l: s5p-fimc: support for dmabuf importing
  Documentation: media: description of DMABUF exporting in V4L2
  v4l: add buffer exporting via dmabuf
  v4l: vb2: add buffer exporting via dmabuf
  v4l: vb2-dma-contig: add support for DMABUF exporting
  v4l: vb2-dma-contig: add reference counting for a device from
allocator context
  v4l: vb2-dma-contig: align buffer size to PAGE_SIZE
  v4l: s5p-fimc: support for dmabuf exporting
  v4l: s5p-tv: mixer: support for dmabuf exporting
  v4l: s5p-mfc: support for dmabuf exporting

 Documentation/DocBook/media/v4l/compat.xml |7 +
 Documentation/DocBook/media/v4l/io.xml |  184 -
 Documentation/DocBook/media/v4l/v4l2.xml   |1 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |   16 +-
 Documentation/DocBook/media/v4l/vidioc-expbuf.xml  |  212 ++
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   17 +
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 +-
 drivers/media/platform/s5p-fimc/fimc-capture.c |   11 +-
 drivers/media/platform/s5p-fimc/fimc-m2m.c |   14 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_dec.c   |   14 +
 drivers/media/platform/s5p-mfc/s5p_mfc_enc.c   |   14 +
 drivers/media/platform/s5p-tv/mixer_video.c|   12 +-
 drivers/media/platform/vivi.c  |2 +-
 drivers/media/v4l2-core/Kconfig|3 +
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c  |   19 +
 drivers/media/v4l2-core/v4l2-dev.c |1 +
 drivers/media/v4l2-core/v4l2-ioctl.c   |   11 +
 drivers/media/v4l2-core/v4l2-mem2mem.c |   13 +
 drivers/media/v4l2-core/videobuf-core.c|4 +
 drivers/media/v4l2-core/videobuf2-core.c   |  300 -
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  702 ++--
 drivers/media/v4l2-core/videobuf2-memops.c |   40 --
 drivers/media/v4l2-core/videobuf2-vmalloc.c|   56 ++
 include/linux/videodev2.h  |   35 +
 include/media/v4l2-ioctl.h |2 +
 include/media/v4l2-mem2mem.h   |3 +
 include/media/videobuf2-core.h |   38 ++
 include/media/videobuf2-memops.h   |5 -
 28 files changed, 1645 insertions(+), 138 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml

-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 01/26] v4l: Add DMABUF as a memory type

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal sumit.sem...@ti.com

Adds DMABUF memory type to v4l framework. Also adds the related file
descriptor in v4l2_plane and v4l2_buffer.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal sumit.sem...@ti.com
Signed-off-by: Sumit Semwal sumit.sem...@linaro.org
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |   18 ++
 drivers/media/v4l2-core/v4l2-ioctl.c  |1 +
 include/linux/videodev2.h |7 +++
 3 files changed, 26 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 83ffb64..cc5998b 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -297,6 +297,7 @@ struct v4l2_plane32 {
union {
__u32   mem_offset;
compat_long_t   userptr;
+   __s32   fd;
} m;
__u32   data_offset;
__u32   reserved[11];
@@ -318,6 +319,7 @@ struct v4l2_buffer32 {
__u32   offset;
compat_long_t   userptr;
compat_caddr_t  planes;
+   __s32   fd;
} m;
__u32   length;
__u32   reserved2;
@@ -341,6 +343,9 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
up_pln = compat_ptr(p);
if (put_user((unsigned long)up_pln, up-m.userptr))
return -EFAULT;
+   } else if (memory == V4L2_MEMORY_DMABUF) {
+   if (copy_in_user(up-m.fd, up32-m.fd, sizeof(int)))
+   return -EFAULT;
} else {
if (copy_in_user(up-m.mem_offset, up32-m.mem_offset,
sizeof(__u32)))
@@ -364,6 +369,11 @@ static int put_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
if (copy_in_user(up32-m.mem_offset, up-m.mem_offset,
sizeof(__u32)))
return -EFAULT;
+   /* For DMABUF, driver might've set up the fd, so copy it back. */
+   if (memory == V4L2_MEMORY_DMABUF)
+   if (copy_in_user(up32-m.fd, up-m.fd,
+   sizeof(int)))
+   return -EFAULT;
 
return 0;
 }
@@ -446,6 +456,10 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (get_user(kp-m.offset, up-m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (get_user(kp-m.fd, up-m.fd))
+   return -EFAULT;
+   break;
}
}
 
@@ -510,6 +524,10 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (put_user(kp-m.offset, up-m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (put_user(kp-m.fd, up-m.fd))
+   return -EFAULT;
+   break;
}
}
 
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 8f388ff..530a67e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -155,6 +155,7 @@ static const char *v4l2_memory_names[] = {
[V4L2_MEMORY_MMAP]= mmap,
[V4L2_MEMORY_USERPTR] = userptr,
[V4L2_MEMORY_OVERLAY] = overlay,
+   [V4L2_MEMORY_DMABUF] = dmabuf,
 };
 
 #define prt_names(a, arr) (((unsigned)(a))  ARRAY_SIZE(arr) ? arr[a] : 
unknown)
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 873adbe..07bc5d6 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -188,6 +188,7 @@ enum v4l2_memory {
V4L2_MEMORY_MMAP = 1,
V4L2_MEMORY_USERPTR  = 2,
V4L2_MEMORY_OVERLAY  = 3,
+   V4L2_MEMORY_DMABUF   = 4,
 };
 
 /* see also http://vektor.theorem.ca/graphics/ycbcr/ */
@@ -604,6 +605,8 @@ struct v4l2_requestbuffers {
  * should be passed to mmap() called on the video node)
  * @userptr:   when memory is V4L2_MEMORY_USERPTR, a userspace pointer
  * pointing to this plane
+ * @fd:when memory is V4L2_MEMORY_DMABUF, a userspace 
file
+ * descriptor associated with this plane
  * @data_offset:   offset in the plane to the start of data; usually 0,
  * unless there is a header

[PATCHv10 02/26] Documentation: media: description of DMABUF importing in V4L2

2012-10-10 Thread Tomasz Stanislawski
This patch adds description and usage examples for importing
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
CC: linux-...@vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml |4 +
 Documentation/DocBook/media/v4l/io.xml |  181 +++-
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |   16 +-
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   17 ++
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 ++---
 5 files changed, 235 insertions(+), 30 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index 4fdf6b5..50eb630 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2586,6 +2586,10 @@ ioctls./para
  paraVendor and device specific media bus pixel formats.
xref linkend=v4l2-mbus-vendor-spec-fmts /./para
 /listitem
+listitem
+ paraImporting DMABUF file descriptors as a new IO method described
+ in xref linkend=dmabuf /./para
+/listitem
   /itemizedlist
 /section
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index b5d1cbd..0abb5cb 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -331,7 +331,7 @@ application until one or more buffers can be dequeued. By 
default
 outgoing queue. When the constantO_NONBLOCK/constant flag was
 given to the func-open; function, constantVIDIOC_DQBUF/constant
 returns immediately with an EAGAIN; when no buffer is available. The
-func-select; or func-poll; function are always available./para
+func-select; or func-poll; functions are always available./para
 
 paraTo start and stop capturing or output applications call the
 VIDIOC-STREAMON; and VIDIOC-STREAMOFF; ioctl. Note
@@ -472,6 +472,162 @@ rest should be evident./para
   /footnote/para
   /section
 
+  section id=dmabuf
+titleStreaming I/O (DMA buffer importing)/title
+
+note
+  titleExperimental/title
+  paraThis is an link linkend=experimental experimental /link
+  interface and may change in the future./para
+/note
+
+paraThe DMABUF framework provides a generic method for sharing buffers
+between multiple devices. Device drivers that support DMABUF can export a DMA
+buffer to userspace as a file descriptor (known as the exporter role), import a
+DMA buffer from userspace using a file descriptor previously exported for a
+different or the same device (known as the importer role), or both. This
+section describes the DMABUF importer role API in V4L2./para
+
+paraInput and output devices support the streaming I/O method when the
+constantV4L2_CAP_STREAMING/constant flag in the
+structfieldcapabilities/structfield field of v4l2-capability; returned by
+the VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through
+DMABUF file descriptors is supported is determined by calling the
+VIDIOC-REQBUFS; ioctl with the memory type set to
+constantV4L2_MEMORY_DMABUF/constant./para
+
+paraThis I/O method is dedicated to sharing DMA buffers between different
+devices, which may be V4L devices or other video-related devices (e.g. DRM).
+Buffers (planes) are allocated by a driver on behalf of an application. Next,
+these buffers are exported to the application as file descriptors using an API
+which is specific for an allocator driver.  Only such file descriptor are
+exchanged. The descriptors and meta-information are passed in v4l2-buffer; (or
+in v4l2-plane; in the multi-planar API case).  The driver must be switched
+into DMABUF I/O mode by calling the VIDIOC-REQBUFS; with the desired buffer
+type./para
+
+example
+  titleInitiating streaming I/O with DMABUF file descriptors/title
+
+  programlisting
+v4l2-requestbuffers; reqbuf;
+
+memset(amp;reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_DMABUF;
+reqbuf.count = 1;
+
+if (ioctl(fd, VIDIOC-REQBUFS;, amp;reqbuf) == -1) {
+   if (errno == EINVAL)
+   printf(Video capturing or DMABUF streaming is not 
supported\n);
+   else
+   perror(VIDIOC_REQBUFS);
+
+   exit(EXIT_FAILURE);
+}
+  /programlisting
+/example
+
+paraThe buffer (plane) file descriptor is passed on the fly with the
+VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be
+associated with a different DMABUF descriptor. Although buffers are commonly
+cycled, applications can pass a different DMABUF descriptor at each
+constantVIDIOC_QBUF/constant call./para
+
+example
+  titleQueueing DMABUF using single plane API/title
+
+  programlisting
+int buffer_queue(int v4lfd, int index, int dmafd)
+{
+   v4l2-buffer; buf;
+
+   memset(amp;buf, 0, sizeof buf);
+   buf.type

[PATCHv10 03/26] v4l: vb2: add support for shared buffer (dma_buf)

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal sumit.sem...@ti.com

This patch adds support for DMABUF memory type in videobuf2. It calls relevant
APIs of dma_buf for v4l reqbuf / qbuf / dqbuf operations.

For this version, the support is for videobuf2 as a user of the shared buffer;
so the allocation of the buffer is done outside of V4L2. [A sample allocator of
dma-buf shared buffer is given at [1]]

[1]: Rob Clark's DRM:
   https://github.com/robclark/kernel-omap4/commits/drmplane-dmabuf

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal sumit.sem...@ti.com
Signed-off-by: Sumit Semwal sumit.sem...@linaro.org
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/Kconfig  |1 +
 drivers/media/v4l2-core/videobuf2-core.c |  206 +-
 include/media/videobuf2-core.h   |   27 
 3 files changed, 231 insertions(+), 3 deletions(-)

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 0c54e19..2e787cc 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -59,6 +59,7 @@ config VIDEOBUF_DVB
 
 # Used by drivers that need Videobuf2 modules
 config VIDEOBUF2_CORE
+   select DMA_SHARED_BUFFER
tristate
 
 config VIDEOBUF2_MEMOPS
diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 432df11..a51dad6 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -109,6 +109,36 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
 }
 
 /**
+ * __vb2_plane_dmabuf_put() - release memory associated with
+ * a DMABUF shared plane
+ */
+static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
+{
+   if (!p-mem_priv)
+   return;
+
+   if (p-dbuf_mapped)
+   call_memop(q, unmap_dmabuf, p-mem_priv);
+
+   call_memop(q, detach_dmabuf, p-mem_priv);
+   dma_buf_put(p-dbuf);
+   memset(p, 0, sizeof(*p));
+}
+
+/**
+ * __vb2_buf_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
+{
+   struct vb2_queue *q = vb-vb2_queue;
+   unsigned int plane;
+
+   for (plane = 0; plane  vb-num_planes; ++plane)
+   __vb2_plane_dmabuf_put(q, vb-planes[plane]);
+}
+
+/**
  * __setup_offsets() - setup unique offsets (cookies) for every plane in
  * every buffer on the queue
  */
@@ -230,6 +260,8 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned 
int buffers)
/* Free MMAP buffers or release USERPTR buffers */
if (q-memory == V4L2_MEMORY_MMAP)
__vb2_buf_mem_free(vb);
+   else if (q-memory == V4L2_MEMORY_DMABUF)
+   __vb2_buf_dmabuf_put(vb);
else
__vb2_buf_userptr_put(vb);
}
@@ -362,6 +394,8 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, 
struct v4l2_buffer *b)
b-m.offset = vb-v4l2_planes[0].m.mem_offset;
else if (q-memory == V4L2_MEMORY_USERPTR)
b-m.userptr = vb-v4l2_planes[0].m.userptr;
+   else if (q-memory == V4L2_MEMORY_DMABUF)
+   b-m.fd = vb-v4l2_planes[0].m.fd;
}
 
/*
@@ -454,13 +488,28 @@ static int __verify_mmap_ops(struct vb2_queue *q)
 }
 
 /**
+ * __verify_dmabuf_ops() - verify that all memory operations required for
+ * DMABUF queue type have been provided
+ */
+static int __verify_dmabuf_ops(struct vb2_queue *q)
+{
+   if (!(q-io_modes  VB2_DMABUF) || !q-mem_ops-attach_dmabuf ||
+   !q-mem_ops-detach_dmabuf  || !q-mem_ops-map_dmabuf ||
+   !q-mem_ops-unmap_dmabuf)
+   return -EINVAL;
+
+   return 0;
+}
+
+/**
  * __verify_memory_type() - Check whether the memory type and buffer type
  * passed to a buffer operation are compatible with the queue.
  */
 static int __verify_memory_type(struct vb2_queue *q,
enum v4l2_memory memory, enum v4l2_buf_type type)
 {
-   if (memory != V4L2_MEMORY_MMAP  memory != V4L2_MEMORY_USERPTR) {
+   if (memory != V4L2_MEMORY_MMAP  memory != V4L2_MEMORY_USERPTR 
+   memory != V4L2_MEMORY_DMABUF) {
dprintk(1, reqbufs: unsupported memory type\n);
return -EINVAL;
}
@@ -484,6 +533,11 @@ static int __verify_memory_type(struct vb2_queue *q,
return -EINVAL;
}
 
+   if (memory == V4L2_MEMORY_DMABUF  __verify_dmabuf_ops(q)) {
+   dprintk(1, reqbufs: DMABUF for current setup unsupported\n);
+   return -EINVAL;
+   }
+
/*
 * Place the busy tests at the end: -EBUSY can be ignored when
 * create_bufs is called with count == 0, but count == 0 should still

[PATCHv10 04/26] v4l: vb: remove warnings about MEMORY_DMABUF

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal sumit.sem...@ti.com

Adding DMABUF memory type causes videobuf to complain about not using it
in some switch cases. This patch removes these warnings.

Signed-off-by: Sumit Semwal sumit.sem...@ti.com
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/videobuf-core.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf-core.c 
b/drivers/media/v4l2-core/videobuf-core.c
index bf7a326..5449e8a 100644
--- a/drivers/media/v4l2-core/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
@@ -335,6 +335,9 @@ static void videobuf_status(struct videobuf_queue *q, 
struct v4l2_buffer *b,
case V4L2_MEMORY_OVERLAY:
b-m.offset  = vb-boff;
break;
+   case V4L2_MEMORY_DMABUF:
+   /* DMABUF is not handled in videobuf framework */
+   break;
}
 
b-flags= 0;
@@ -405,6 +408,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
break;
case V4L2_MEMORY_USERPTR:
case V4L2_MEMORY_OVERLAY:
+   case V4L2_MEMORY_DMABUF:
/* nothing */
break;
}
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 05/26] v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc

2012-10-10 Thread Tomasz Stanislawski
From: Laurent Pinchart laurent.pinch...@ideasonboard.com

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   36 
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 4b71326..a05784f 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -32,9 +32,9 @@ struct vb2_dc_buf {
struct vb2_vmarea_handler   handler;
 };
 
-static void vb2_dma_contig_put(void *buf_priv);
+static void vb2_dc_put(void *buf_priv);
 
-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
+static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
@@ -56,7 +56,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
buf-size = size;
 
buf-handler.refcount = buf-refcount;
-   buf-handler.put = vb2_dma_contig_put;
+   buf-handler.put = vb2_dc_put;
buf-handler.arg = buf;
 
atomic_inc(buf-refcount);
@@ -64,7 +64,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
return buf;
 }
 
-static void vb2_dma_contig_put(void *buf_priv)
+static void vb2_dc_put(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -75,14 +75,14 @@ static void vb2_dma_contig_put(void *buf_priv)
}
 }
 
-static void *vb2_dma_contig_cookie(void *buf_priv)
+static void *vb2_dc_cookie(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return buf-dma_addr;
 }
 
-static void *vb2_dma_contig_vaddr(void *buf_priv)
+static void *vb2_dc_vaddr(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
if (!buf)
@@ -91,14 +91,14 @@ static void *vb2_dma_contig_vaddr(void *buf_priv)
return buf-vaddr;
 }
 
-static unsigned int vb2_dma_contig_num_users(void *buf_priv)
+static unsigned int vb2_dc_num_users(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return atomic_read(buf-refcount);
 }
 
-static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
+static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -111,7 +111,7 @@ static int vb2_dma_contig_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  vb2_common_vm_ops, buf-handler);
 }
 
-static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
struct vb2_dc_buf *buf;
@@ -138,7 +138,7 @@ static void *vb2_dma_contig_get_userptr(void *alloc_ctx, 
unsigned long vaddr,
return buf;
 }
 
-static void vb2_dma_contig_put_userptr(void *mem_priv)
+static void vb2_dc_put_userptr(void *mem_priv)
 {
struct vb2_dc_buf *buf = mem_priv;
 
@@ -150,14 +150,14 @@ static void vb2_dma_contig_put_userptr(void *mem_priv)
 }
 
 const struct vb2_mem_ops vb2_dma_contig_memops = {
-   .alloc  = vb2_dma_contig_alloc,
-   .put= vb2_dma_contig_put,
-   .cookie = vb2_dma_contig_cookie,
-   .vaddr  = vb2_dma_contig_vaddr,
-   .mmap   = vb2_dma_contig_mmap,
-   .get_userptr= vb2_dma_contig_get_userptr,
-   .put_userptr= vb2_dma_contig_put_userptr,
-   .num_users  = vb2_dma_contig_num_users,
+   .alloc  = vb2_dc_alloc,
+   .put= vb2_dc_put,
+   .cookie = vb2_dc_cookie,
+   .vaddr  = vb2_dc_vaddr,
+   .mmap   = vb2_dc_mmap,
+   .get_userptr= vb2_dc_get_userptr,
+   .put_userptr= vb2_dc_put_userptr,
+   .num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
 
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 06/26] v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer

2012-10-10 Thread Tomasz Stanislawski
This patch removes a reference to alloc_ctx from an instance of a DMA
contiguous buffer. It helps to avoid a risk of a dangling pointer if the
context is released while the buffer is still valid. Moreover it removes one
dereference step while accessing a device structure.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index a05784f..20c95da 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -23,7 +23,7 @@ struct vb2_dc_conf {
 };
 
 struct vb2_dc_buf {
-   struct vb2_dc_conf  *conf;
+   struct device   *dev;
void*vaddr;
dma_addr_t  dma_addr;
unsigned long   size;
@@ -37,22 +37,21 @@ static void vb2_dc_put(void *buf_priv);
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
+   struct device *dev = conf-dev;
struct vb2_dc_buf *buf;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
 
-   buf-vaddr = dma_alloc_coherent(conf-dev, size, buf-dma_addr,
-   GFP_KERNEL);
+   buf-vaddr = dma_alloc_coherent(dev, size, buf-dma_addr, GFP_KERNEL);
if (!buf-vaddr) {
-   dev_err(conf-dev, dma_alloc_coherent of size %ld failed\n,
-   size);
+   dev_err(dev, dma_alloc_coherent of size %ld failed\n, size);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
 
-   buf-conf = conf;
+   buf-dev = dev;
buf-size = size;
 
buf-handler.refcount = buf-refcount;
@@ -69,7 +68,7 @@ static void vb2_dc_put(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
 
if (atomic_dec_and_test(buf-refcount)) {
-   dma_free_coherent(buf-conf-dev, buf-size, buf-vaddr,
+   dma_free_coherent(buf-dev, buf-size, buf-vaddr,
  buf-dma_addr);
kfree(buf);
}
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 07/26] v4l: vb2-dma-contig: reorder functions

2012-10-10 Thread Tomasz Stanislawski
From: Laurent Pinchart laurent.pinch...@ideasonboard.com

Group functions by buffer type.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   92 ++--
 1 file changed, 54 insertions(+), 38 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 20c95da..daac2b2 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -25,14 +25,56 @@ struct vb2_dc_conf {
 struct vb2_dc_buf {
struct device   *dev;
void*vaddr;
-   dma_addr_t  dma_addr;
unsigned long   size;
-   struct vm_area_struct   *vma;
-   atomic_trefcount;
+   dma_addr_t  dma_addr;
+
+   /* MMAP related */
struct vb2_vmarea_handler   handler;
+   atomic_trefcount;
+
+   /* USERPTR related */
+   struct vm_area_struct   *vma;
 };
 
-static void vb2_dc_put(void *buf_priv);
+/*/
+/* callbacks for all buffers */
+/*/
+
+static void *vb2_dc_cookie(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return buf-dma_addr;
+}
+
+static void *vb2_dc_vaddr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return buf-vaddr;
+}
+
+static unsigned int vb2_dc_num_users(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return atomic_read(buf-refcount);
+}
+
+/*/
+/*callbacks for MMAP buffers */
+/*/
+
+static void vb2_dc_put(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   if (!atomic_dec_and_test(buf-refcount))
+   return;
+
+   dma_free_coherent(buf-dev, buf-size, buf-vaddr, buf-dma_addr);
+   kfree(buf);
+}
 
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
@@ -63,40 +105,6 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
return buf;
 }
 
-static void vb2_dc_put(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   if (atomic_dec_and_test(buf-refcount)) {
-   dma_free_coherent(buf-dev, buf-size, buf-vaddr,
- buf-dma_addr);
-   kfree(buf);
-   }
-}
-
-static void *vb2_dc_cookie(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return buf-dma_addr;
-}
-
-static void *vb2_dc_vaddr(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-   if (!buf)
-   return NULL;
-
-   return buf-vaddr;
-}
-
-static unsigned int vb2_dc_num_users(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return atomic_read(buf-refcount);
-}
-
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
@@ -110,6 +118,10 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  vb2_common_vm_ops, buf-handler);
 }
 
+/*/
+/*   callbacks for USERPTR buffers   */
+/*/
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
@@ -148,6 +160,10 @@ static void vb2_dc_put_userptr(void *mem_priv)
kfree(buf);
 }
 
+/*/
+/*   DMA CONTIG exported functions   */
+/*/
+
 const struct vb2_mem_ops vb2_dma_contig_memops = {
.alloc  = vb2_dc_alloc,
.put= vb2_dc_put,
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 08/26] v4l: vb2-dma-contig: add support for scatterlist in userptr mode

2012-10-10 Thread Tomasz Stanislawski
This patch introduces usage of dma_map_sg to map memory behind
a userspace pointer to a device as dma-contiguous mapping.

This patch contains some of the code kindly provided by Marek Szyprowski
m.szyprow...@samsung.com and Kamil Debski k.deb...@samsung.com and Andrzej
Pietrasiewicz andrze...@samsung.com. Kind thanks for bug reports from Laurent
Pinchart laurent.pinch...@ideasonboard.com and Seung-Woo Kim
sw0312@samsung.com.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  226 ++--
 1 file changed, 210 insertions(+), 16 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index daac2b2..8486e06 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -11,6 +11,8 @@
  */
 
 #include linux/module.h
+#include linux/scatterlist.h
+#include linux/sched.h
 #include linux/slab.h
 #include linux/dma-mapping.h
 
@@ -27,6 +29,8 @@ struct vb2_dc_buf {
void*vaddr;
unsigned long   size;
dma_addr_t  dma_addr;
+   enum dma_data_direction dma_dir;
+   struct sg_table *dma_sgt;
 
/* MMAP related */
struct vb2_vmarea_handler   handler;
@@ -37,6 +41,44 @@ struct vb2_dc_buf {
 };
 
 /*/
+/*scatterlist table functions*/
+/*/
+
+
+static void vb2_dc_sgt_foreach_page(struct sg_table *sgt,
+   void (*cb)(struct page *pg))
+{
+   struct scatterlist *s;
+   unsigned int i;
+
+   for_each_sg(sgt-sgl, s, sgt-orig_nents, i) {
+   struct page *page = sg_page(s);
+   unsigned int n_pages = PAGE_ALIGN(s-offset + s-length)
+PAGE_SHIFT;
+   unsigned int j;
+
+   for (j = 0; j  n_pages; ++j, ++page)
+   cb(page);
+   }
+}
+
+static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt)
+{
+   struct scatterlist *s;
+   dma_addr_t expected = sg_dma_address(sgt-sgl);
+   unsigned int i;
+   unsigned long size = 0;
+
+   for_each_sg(sgt-sgl, s, sgt-nents, i) {
+   if (sg_dma_address(s) != expected)
+   break;
+   expected = sg_dma_address(s) + sg_dma_len(s);
+   size += sg_dma_len(s);
+   }
+   return size;
+}
+
+/*/
 /* callbacks for all buffers */
 /*/
 
@@ -122,42 +164,194 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 /*   callbacks for USERPTR buffers   */
 /*/
 
+static inline int vma_is_io(struct vm_area_struct *vma)
+{
+   return !!(vma-vm_flags  (VM_IO | VM_PFNMAP));
+}
+
+static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+   int n_pages, struct vm_area_struct *vma, int write)
+{
+   if (vma_is_io(vma)) {
+   unsigned int i;
+
+   for (i = 0; i  n_pages; ++i, start += PAGE_SIZE) {
+   unsigned long pfn;
+   int ret = follow_pfn(vma, start, pfn);
+
+   if (ret) {
+   pr_err(no page for address %lu\n, start);
+   return ret;
+   }
+   pages[i] = pfn_to_page(pfn);
+   }
+   } else {
+   int n;
+
+   n = get_user_pages(current, current-mm, start  PAGE_MASK,
+   n_pages, write, 1, pages, NULL);
+   /* negative error means that no page was pinned */
+   n = max(n, 0);
+   if (n != n_pages) {
+   pr_err(got only %d of %d user pages\n, n, n_pages);
+   while (n)
+   put_page(pages[--n]);
+   return -EFAULT;
+   }
+   }
+
+   return 0;
+}
+
+static void vb2_dc_put_dirty_page(struct page *page)
+{
+   set_page_dirty_lock(page);
+   put_page(page);
+}
+
+static void vb2_dc_put_userptr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf-dma_sgt;
+
+   dma_unmap_sg(buf-dev, sgt-sgl, sgt-orig_nents, buf-dma_dir);
+   if (!vma_is_io(buf-vma))
+   vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
+
+   sg_free_table(sgt);
+   kfree(sgt);
+   vb2_put_vma(buf-vma);
+   kfree(buf);
+}
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr

[PATCHv10 09/26] v4l: vb2: add prepare/finish callbacks to allocators

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski m.szyprow...@samsung.com

This patch adds support for prepare/finish callbacks in VB2 allocators. These
callback are used for buffer flushing.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/videobuf2-core.c |   11 +++
 include/media/videobuf2-core.h   |7 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index a51dad6..613dea1 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -844,6 +844,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
 {
struct vb2_queue *q = vb-vb2_queue;
unsigned long flags;
+   unsigned int plane;
 
if (vb-state != VB2_BUF_STATE_ACTIVE)
return;
@@ -854,6 +855,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
dprintk(4, Done processing on buffer %d, state: %d\n,
vb-v4l2_buf.index, vb-state);
 
+   /* sync buffers */
+   for (plane = 0; plane  vb-num_planes; ++plane)
+   call_memop(q, finish, vb-planes[plane].mem_priv);
+
/* Add the buffer to the done buffers list */
spin_lock_irqsave(q-done_lock, flags);
vb-state = state;
@@ -1136,9 +1141,15 @@ err:
 static void __enqueue_in_driver(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb-vb2_queue;
+   unsigned int plane;
 
vb-state = VB2_BUF_STATE_ACTIVE;
atomic_inc(q-queued_count);
+
+   /* sync buffers */
+   for (plane = 0; plane  vb-num_planes; ++plane)
+   call_memop(q, prepare, vb-planes[plane].mem_priv);
+
q-ops-buf_queue(vb);
 }
 
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 689ae4a..24b9c90 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -56,6 +56,10 @@ struct vb2_fileio_data;
  * dmabuf
  * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
  *   that this driver is done using the dmabuf for now
+ * @prepare:   called every time the buffer is passed from userspace to the
+ * driver, useful for cache synchronisation, optional
+ * @finish:called every time the buffer is passed back from the driver
+ * to the userspace, also optional
  * @vaddr: return a kernel virtual address to a given memory buffer
  * associated with the passed private structure or NULL if no
  * such mapping exists
@@ -82,6 +86,9 @@ struct vb2_mem_ops {
unsigned long size, int write);
void(*put_userptr)(void *buf_priv);
 
+   void(*prepare)(void *buf_priv);
+   void(*finish)(void *buf_priv);
+
void*(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf,
unsigned long size, int write);
void(*detach_dmabuf)(void *buf_priv);
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 10/26] v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski m.szyprow...@samsung.com

Add prepare/finish callbacks to vb2-dma-contig allocator.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Hans Verkuil hans.verk...@cisco.com
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 8486e06..494a824 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -103,6 +103,28 @@ static unsigned int vb2_dc_num_users(void *buf_priv)
return atomic_read(buf-refcount);
 }
 
+static void vb2_dc_prepare(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf-dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_device(buf-dev, sgt-sgl, sgt-nents, buf-dma_dir);
+}
+
+static void vb2_dc_finish(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf-dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_cpu(buf-dev, sgt-sgl, sgt-nents, buf-dma_dir);
+}
+
 /*/
 /*callbacks for MMAP buffers */
 /*/
@@ -366,6 +388,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = {
.mmap   = vb2_dc_mmap,
.get_userptr= vb2_dc_get_userptr,
.put_userptr= vb2_dc_put_userptr,
+   .prepare= vb2_dc_prepare,
+   .finish = vb2_dc_finish,
.num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv10 11/26] v4l: vb2-dma-contig: add support for dma_buf importing

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal sumit.sem...@ti.com

This patch makes changes for adding dma-contig as a dma_buf user. It provides
function implementations for the {attach, detach, map, unmap}_dmabuf()
mem_ops of DMABUF memory type.

Signed-off-by: Sumit Semwal sumit.sem...@ti.com
Signed-off-by: Sumit Semwal sumit.sem...@linaro.org
[author of the original patch]
Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
[integration with refactored dma-contig allocator]
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/v4l2-core/Kconfig|1 +
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  120 +++-
 2 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 2e787cc..e30583b 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -69,6 +69,7 @@ config VIDEOBUF2_DMA_CONTIG
tristate
select VIDEOBUF2_CORE
select VIDEOBUF2_MEMOPS
+   select DMA_SHARED_BUFFER
 
 config VIDEOBUF2_VMALLOC
tristate
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 494a824..a5804cf 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  */
 
+#include linux/dma-buf.h
 #include linux/module.h
 #include linux/scatterlist.h
 #include linux/sched.h
@@ -38,6 +39,9 @@ struct vb2_dc_buf {
 
/* USERPTR related */
struct vm_area_struct   *vma;
+
+   /* DMABUF related */
+   struct dma_buf_attachment   *db_attach;
 };
 
 /*/
@@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf-dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf-db_attach)
return;
 
dma_sync_sg_for_device(buf-dev, sgt-sgl, sgt-nents, buf-dma_dir);
@@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf-dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf-db_attach)
return;
 
dma_sync_sg_for_cpu(buf-dev, sgt-sgl, sgt-nents, buf-dma_dir);
@@ -377,6 +383,112 @@ fail_buf:
 }
 
 /*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_dc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt;
+   unsigned long contig_size;
+
+   if (WARN_ON(!buf-db_attach)) {
+   pr_err(trying to pin a non attached buffer\n);
+   return -EINVAL;
+   }
+
+   if (WARN_ON(buf-dma_sgt)) {
+   pr_err(dmabuf buffer is already pinned\n);
+   return 0;
+   }
+
+   /* get the associated scatterlist for this buffer */
+   sgt = dma_buf_map_attachment(buf-db_attach, buf-dma_dir);
+   if (IS_ERR_OR_NULL(sgt)) {
+   pr_err(Error getting dmabuf scatterlist\n);
+   return -EINVAL;
+   }
+
+   /* checking if dmabuf is big enough to store contiguous chunk */
+   contig_size = vb2_dc_get_contiguous_size(sgt);
+   if (contig_size  buf-size) {
+   pr_err(contiguous chunk is too small %lu/%lu b\n,
+   contig_size, buf-size);
+   dma_buf_unmap_attachment(buf-db_attach, sgt, buf-dma_dir);
+   return -EFAULT;
+   }
+
+   buf-dma_addr = sg_dma_address(sgt-sgl);
+   buf-dma_sgt = sgt;
+
+   return 0;
+}
+
+static void vb2_dc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt = buf-dma_sgt;
+
+   if (WARN_ON(!buf-db_attach)) {
+   pr_err(trying to unpin a not attached buffer\n);
+   return;
+   }
+
+   if (WARN_ON(!sgt)) {
+   pr_err(dmabuf buffer is already unpinned\n);
+   return;
+   }
+
+   dma_buf_unmap_attachment(buf-db_attach, sgt, buf-dma_dir);
+
+   buf-dma_addr = 0;
+   buf-dma_sgt = NULL;
+}
+
+static void vb2_dc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+
+   /* if vb2 works correctly you should never detach mapped buffer */
+   if (WARN_ON(buf-dma_addr))
+   vb2_dc_unmap_dmabuf(buf);
+
+   /* detach this attachment */
+   dma_buf_detach(buf-db_attach-dmabuf, buf-db_attach);
+   kfree(buf);
+}
+
+static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_dc_conf *conf = alloc_ctx;
+   struct vb2_dc_buf *buf

  1   2   3   4   5   6   >