Re: [RFC PATCH 1/6] ARM: OMAP2+: hwmod: add parent_hwmod support

2014-10-09 Thread Archit Taneja
Hi,

On Thu, Oct 9, 2014 at 7:33 PM, Tomi Valkeinen tomi.valkei...@ti.com wrote:
 Add parent_hwmod pointer to omap_hwmod. This can be set to point to a
 parent hwmod that needs to be enabled for the child hwmod to work.

 This is used at hwmod setup time: when doing the initial setup and
 reset, first enable the parent hwmod, and after setup and reset is done,
 restore the parent hwmod to postsetup_state.


This method is better. It's less intrusive and only takes place at setup time.

Reviewed-by: Archit Taneja archit.tan...@gmail.com
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/6] ARM: OMAP4+: hwmod: fixing omap4+ DSS hwmods

2014-10-09 Thread Archit Taneja
On Thu, Oct 9, 2014 at 7:33 PM, Tomi Valkeinen tomi.valkei...@ti.com wrote:
 This is an RFC to fix the issues with boot time DSS hwmod setup.

 There was an earlier series sent by Archit here:

 http://www.spinics.net/lists/linux-omap/msg107700.html

 This series takes different approach, and just tries to fix the issue at setup
 time by making sure the DSS core hwmod is enabled when a DSS submodule hwmod 
 is
 being setup.

 Quickly tested on OMAP4 Panda and OMAP5 uEVM.

The series looks good to me.

Reviewed-by: Archit Taneja archit.tan...@gmail.com

Archit
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 15/15] drm/omap: Add infoframe dvi/hdmi mode support

2014-06-25 Thread Archit Taneja

Hi,

On Tuesday 24 June 2014 03:34 PM, Tomi Valkeinen wrote:

Make the omapdrm driver use the new HDMI ops when possible.

omapdrm will call set_hdmi_mode (when available) to tell the encoder
driver whether the monitor is a DVI or HDMI monitor, and if it's an HDMI
monitor, omapdrm will call set_hdmi_infoframe to to set the AVI
infoframe.


snip



@@ -89,6 +91,31 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
  {
+   struct drm_device *dev = encoder-dev;
+   struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+   struct omap_dss_device *dssdev = omap_encoder-dssdev;
+   struct drm_connector *connector;
+   bool hdmi_mode;
+   int r;
+
+   hdmi_mode = false;
+   list_for_each_entry(connector, dev-mode_config.connector_list, head) {
+   if (connector-encoder == encoder) {
+   hdmi_mode = omap_connector_get_hdmi_mode(connector);
+   break;
+   }
+   }
+
+   if (dssdev-driver-set_hdmi_mode)
+   dssdev-driver-set_hdmi_mode(dssdev, hdmi_mode);


When a HDMI monitor is replaced with a DVI one, we call the 
set_hdmi_mode() driver op to set the mode to DVI. But we don't call 
set_hdmi_infoframe() when the mode is set back to DVI. Do we need to set 
avi infoframe registers back to a default value, or are those registers 
just ignored in DVI mode?



+
+   if (hdmi_mode  dssdev-driver-set_hdmi_infoframe) {
+   struct hdmi_avi_infoframe avi;
+
+   r = drm_hdmi_avi_infoframe_from_display_mode(avi, 
adjusted_mode);
+   if (r == 0)
+   dssdev-driver-set_hdmi_infoframe(dssdev, avi);
+   }
  }



Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 0/2] arm: omap2+: hwmod: Allow hwmods to share same modulemode register filed

2014-06-17 Thread Archit Taneja
IP blocks within a clock domain generally come with their own CM_X_CLKCTRL
registers, each having it's own MODULEMODE field to manage the module. This is
not the case for DSS, though. DSS contains contains sub modules, each of which
are represented by hwmods, but DSS itself has only one register
CM_DSS_DSS_CLKCTRL.

Add a way to allow multiple hwmods to share the same MODULEMODE fiels. This
means that MODULEMODE operation should be disabled only when the last hwmod
using it is disabled.

Changes in v2:

- The OMAP4 PRCM hwmod flag to show that this hwmod is shared was found
  redundant, and therefore, removed.
- Some of the struct names are shortened, and members are named more
  appropriately.

Archit Taneja (2):
  arm: omap2+: hwmod: Add refcounting for modulemode shared by multiple
hwmods
  arm: omap5 hwmod data: Example: Make DSS hwmods share MODULEMODE
fields

 arch/arm/mach-omap2/omap_hwmod.c   | 145 +
 arch/arm/mach-omap2/omap_hwmod.h   |  35 +--
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c |  40 +---
 3 files changed, 180 insertions(+), 40 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 2/2] arm: omap5 hwmod data: Example: Make DSS hwmods share MODULEMODE fields

2014-06-17 Thread Archit Taneja
DSS hwmods share the MODULEMODE field. Create a new 'mmode_shared' struct which
the DSS hwmods refer to.

This will allow the hwmods to reset properly during boot, and not break things
when the omapdss module is inserted.

(Note: hdmi and rfbi hwmods still don't reset properly as they don't have their
mainclks as dss_dss_clk, this needs to be changed later).

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 40 --
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 290213f..e855cf5 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -337,6 +337,9 @@ static struct omap_hwmod omap54xx_dmic_hwmod = {
  * 'dss' class
  * display sub-system
  */
+
+static struct mmode_shared dss_modulemode_ref;
+
 static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = {
.rev_offs   = 0x,
.syss_offs  = 0x0014,
@@ -364,9 +367,10 @@ static struct omap_hwmod omap54xx_dss_hwmod = {
.main_clk   = dss_dss_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET,
-   .modulemode   = MODULEMODE_SWCTRL,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .context_offs   = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET,
+   .modulemode = MODULEMODE_SWCTRL,
+   .mmode_ref  = dss_modulemode_ref,
},
},
.opt_clks   = dss_opt_clks,
@@ -414,8 +418,10 @@ static struct omap_hwmod omap54xx_dss_dispc_hwmod = {
.main_clk   = dss_dss_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .modulemode = MODULEMODE_SWCTRL,
+   .mmode_ref  = dss_modulemode_ref,
},
},
.opt_clks   = dss_dispc_opt_clks,
@@ -456,8 +462,10 @@ static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = {
.main_clk   = dss_dss_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .modulemode = MODULEMODE_SWCTRL,
+   .mmode_ref  = dss_modulemode_ref,
},
},
.opt_clks   = dss_dsi1_a_opt_clks,
@@ -476,8 +484,10 @@ static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = {
.main_clk   = dss_dss_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .modulemode = MODULEMODE_SWCTRL,
+   .mmode_ref  = dss_modulemode_ref,
},
},
.opt_clks   = dss_dsi1_c_opt_clks,
@@ -515,8 +525,10 @@ static struct omap_hwmod omap54xx_dss_hdmi_hwmod = {
.main_clk   = dss_48mhz_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .modulemode = MODULEMODE_SWCTRL,
+   .mmode_ref  = dss_modulemode_ref,
},
},
.opt_clks   = dss_hdmi_opt_clks,
@@ -554,8 +566,10 @@ static struct omap_hwmod omap54xx_dss_rfbi_hwmod = {
.clkdm_name = dss_clkdm,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .modulemode = MODULEMODE_SWCTRL,
+   .mmode_ref  = dss_modulemode_ref

[RFC v2 1/2] arm: omap2+: hwmod: Add refcounting for modulemode shared by multiple hwmods

2014-06-17 Thread Archit Taneja
Generally, IP blocks/modules within a clock domain come with their own
CM_x_CLKCTRL registers, each having it's own MODULEMODE field to manage the
module.

DSS clockdomain, however, has multiple modules in it, but only one register
named CM_DSS_DSS_CLKCTRL, which contains one MODULEMODE register field.

Until now, we defined modulemode only for the top level DSS hwmod(dss_core)
and didn't define it for other DSS hwmods(like dss_dispc, dss_dsi1 and so
on). This made the omapdss driver work as the top level DSS platform device
and the rest had a parent-child relationship, and ensured that the parent
hwmod(dss_core) is enabled if any of the children hwmods are enabled.

This method, however, doesn't work when each hwmod is enabled individually. When
hwmods are set up in omap_hwmod_setup_all, each hwmod is individually enabled,
followed by a reset and idle. All the 'children' DSS hwmods fail to enable as
they don't enable modulemode.

The way to make such modules work both during initialization and when used by
pm runtime API in the driver is be to add refcounting for enabling/disabling
modulemode.

We create a struct called 'mmode_shared'. The hwmod data file should define
an instance of this struct. Each hwmod that uses this modulemode field should
hold a pointer to this instance.

omap_hwmod's soc enable_module and disable_module ops set the MODULEMODE
reigster bits only when the first module using it is enabled, or the last
module using it is disabled. We serialize accesses to the struct with a
spinlock.

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod.c | 145 ++-
 arch/arm/mach-omap2/omap_hwmod.h |  35 +++---
 2 files changed, 153 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index f7bb435..2b036e3 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1,3 +1,4 @@
+
 /*
  * omap_hwmod implementation for OMAP2/3/4
  *
@@ -973,17 +974,38 @@ static void _disable_optional_clocks(struct omap_hwmod 
*oh)
  */
 static void _omap4_enable_module(struct omap_hwmod *oh)
 {
+   struct mmode_shared *mmode;
+
if (!oh-clkdm || !oh-prcm.omap4.modulemode)
return;
 
pr_debug(omap_hwmod: %s: %s: %d\n,
 oh-name, __func__, oh-prcm.omap4.modulemode);
 
-   omap4_cminst_module_enable(oh-prcm.omap4.modulemode,
-  oh-clkdm-prcm_partition,
-  oh-clkdm-cm_inst,
-  oh-clkdm-clkdm_offs,
-  oh-prcm.omap4.clkctrl_offs);
+   mmode = oh-prcm.omap4.mmode_ref;
+   if (mmode) {
+   bool enable;
+   unsigned long flags;
+
+   spin_lock_irqsave(mmode-lock, flags);
+
+   enable = mmode-refcnt++ == 0;
+
+   if (enable)
+   omap4_cminst_module_enable(oh-prcm.omap4.modulemode,
+  oh-clkdm-prcm_partition,
+  oh-clkdm-cm_inst,
+  oh-clkdm-clkdm_offs,
+  oh-prcm.omap4.clkctrl_offs);
+
+   spin_unlock_irqrestore(mmode-lock, flags);
+   } else {
+   omap4_cminst_module_enable(oh-prcm.omap4.modulemode,
+  oh-clkdm-prcm_partition,
+  oh-clkdm-cm_inst,
+  oh-clkdm-clkdm_offs,
+  oh-prcm.omap4.clkctrl_offs);
+   }
 }
 
 /**
@@ -995,15 +1017,36 @@ static void _omap4_enable_module(struct omap_hwmod *oh)
  */
 static void _am33xx_enable_module(struct omap_hwmod *oh)
 {
+   struct mmode_shared *mmode;
+
if (!oh-clkdm || !oh-prcm.omap4.modulemode)
return;
 
pr_debug(omap_hwmod: %s: %s: %d\n,
 oh-name, __func__, oh-prcm.omap4.modulemode);
 
-   am33xx_cm_module_enable(oh-prcm.omap4.modulemode, oh-clkdm-cm_inst,
-   oh-clkdm-clkdm_offs,
-   oh-prcm.omap4.clkctrl_offs);
+   mmode = oh-prcm.omap4.mmode_ref;
+   if (mmode) {
+   bool enable;
+   unsigned long flags;
+
+   spin_lock_irqsave(mmode-lock, flags);
+
+   enable = mmode-refcnt++ == 0;
+
+   if (enable)
+   am33xx_cm_module_enable(oh-prcm.omap4.modulemode,
+   oh-clkdm-cm_inst,
+   oh-clkdm-clkdm_offs,
+   oh-prcm.omap4.clkctrl_offs);
+
+   spin_unlock_irqrestore(mmode-lock, flags);
+   } else {
+   am33xx_cm_module_enable(oh-prcm.omap4

[PATCH v3 3/7] OMAPDSS: DPI: Store dpi_data pointer in the DT port's data

2014-06-04 Thread Archit Taneja
DPI and SDI ports are backed by only one parent DSS device. We don't have a
corresponding platform_device for ports under DSS. In order to support multiple
instances of DPI, we need to pass the driver data pointer through the DPI port's
private data ('data' member in device_node struct).

dpi_init_output/dpi_uninit_output are untouched and only used for non-DT case,
these are called when the DPI platform device probed/removed. These funcs will
be removed when non-DT mode is removed.

dpi_init_output_port/dpi_uninit_output_port are created and used for the DT
path, called when DSS inits/uninits it's ports. These new functions retrieve
the dpi_data pointer from 'port-data', and not from the platform device's
data(pdev-dev) like in the non-DT path.

We add some code in dss_uninit_ports() to pass a pointer to the DPI port in
dpi_uninit_port().

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c | 36 ++--
 drivers/video/fbdev/omap2/dss/dss.c | 13 -
 drivers/video/fbdev/omap2/dss/dss.h |  2 +-
 3 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 9087619..b579022 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -59,6 +59,7 @@ static struct dpi_data *dpi_get_data_from_dssdev(struct 
omap_dss_device *dssdev)
return container_of(dssdev, struct dpi_data, output);
 }
 
+/* only used in non-DT mode */
 static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
 {
return dev_get_drvdata(pdev-dev);
@@ -724,6 +725,30 @@ static void __exit dpi_uninit_output(struct 
platform_device *pdev)
omapdss_unregister_output(out);
 }
 
+static void dpi_init_output_port(struct platform_device *pdev,
+   struct device_node *port)
+{
+   struct dpi_data *dpi = port-data;
+   struct omap_dss_device *out = dpi-output;
+
+   out-dev = pdev-dev;
+   out-id = OMAP_DSS_OUTPUT_DPI;
+   out-output_type = OMAP_DISPLAY_TYPE_DPI;
+   out-dispc_channel = dpi_get_channel();
+   out-ops.dpi = dpi_ops;
+   out-owner = THIS_MODULE;
+
+   omapdss_register_output(out);
+}
+
+static void __exit dpi_uninit_output_port(struct device_node *port)
+{
+   struct dpi_data *dpi = port-data;
+   struct omap_dss_device *out = dpi-output;
+
+   omapdss_unregister_output(out);
+}
+
 static int omap_dpi_probe(struct platform_device *pdev)
 {
struct dpi_data *dpi;
@@ -795,15 +820,14 @@ int __init dpi_init_port(struct platform_device *pdev, 
struct device_node *port)
of_node_put(ep);
 
dpi-pdev = pdev;
+   port-data = dpi;
 
mutex_init(dpi-lock);
 
-   dpi_init_output(pdev);
+   dpi_init_output_port(pdev, port);
 
dpi-port_initialized = true;
 
-   dev_set_drvdata(pdev-dev, dpi);
-
return 0;
 
 err_datalines:
@@ -812,12 +836,12 @@ err_datalines:
return r;
 }
 
-void __exit dpi_uninit_port(struct platform_device *pdev)
+void __exit dpi_uninit_port(struct device_node *port)
 {
-   struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
+   struct dpi_data *dpi = port-data;
 
if (!dpi-port_initialized)
return;
 
-   dpi_uninit_output(dpi-pdev);
+   dpi_uninit_output_port(port);
 }
diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index 225b13f..bebb824 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -822,8 +822,19 @@ static int __init dss_init_ports(struct platform_device 
*pdev)
 
 static void __exit dss_uninit_ports(struct platform_device *pdev)
 {
+   struct device_node *parent = pdev-dev.of_node;
+   struct device_node *port;
+   int r;
+
+   if (parent == NULL)
+   return;
+
+   port = omapdss_of_get_next_port(parent, NULL);
+   if (!port)
+   return;
+
 #ifdef CONFIG_OMAP2_DSS_DPI
-   dpi_uninit_port(pdev);
+   dpi_uninit_port(port);
 #endif
 
 #ifdef CONFIG_OMAP2_DSS_SDI
diff --git a/drivers/video/fbdev/omap2/dss/dss.h 
b/drivers/video/fbdev/omap2/dss/dss.h
index da7f5f9..5b9db95 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -359,7 +359,7 @@ int dpi_init_platform_driver(void) __init;
 void dpi_uninit_platform_driver(void) __exit;
 
 int dpi_init_port(struct platform_device *pdev, struct device_node *port) 
__init;
-void dpi_uninit_port(struct platform_device *pdev) __exit;
+void dpi_uninit_port(struct device_node *port) __exit;
 
 /* DISPC */
 int dispc_init_platform_driver(void) __init;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/7] OMAPDSS: DPI: Use DPI driver data

2014-06-04 Thread Archit Taneja
DPI related data is currently a static global struct parameter. It is accessed
directly by functions in the driver.

This method won't work if we want the driver to support multiple DPI instances.
Create struct dpi_data, and pass it's pointer to functions which need to use it.

We still have a static instance defined for dpi_data, which is accessed by top
level DPI ops. This will be removed when the driver dynamically allocates
dpi_data for each DPI instance.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c | 187 +---
 1 file changed, 107 insertions(+), 80 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 9368972..945d988 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -37,7 +37,7 @@
 #include dss.h
 #include dss_features.h
 
-static struct {
+struct dpi_data {
struct platform_device *pdev;
 
struct regulator *vdds_dsi_reg;
@@ -52,7 +52,9 @@ static struct {
struct omap_dss_device output;
 
bool port_initialized;
-} dpi;
+};
+
+static struct dpi_data dpi;
 
 static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
 {
@@ -200,15 +202,16 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
dpi_calc_dispc_cb, ctx);
 }
 
-static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
+static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
+   struct dpi_clk_calc_ctx *ctx)
 {
unsigned long clkin;
unsigned long pll_min, pll_max;
 
-   clkin = dsi_get_pll_clkin(dpi.dsidev);
+   clkin = dsi_get_pll_clkin(dpi-dsidev);
 
memset(ctx, 0, sizeof(*ctx));
-   ctx-dsidev = dpi.dsidev;
+   ctx-dsidev = dpi-dsidev;
ctx-pck_min = pck - 1000;
ctx-pck_max = pck + 1000;
ctx-dsi_cinfo.clkin = clkin;
@@ -216,7 +219,7 @@ static bool dpi_dsi_clk_calc(unsigned long pck, struct 
dpi_clk_calc_ctx *ctx)
pll_min = 0;
pll_max = 0;
 
-   return dsi_pll_calc(dpi.dsidev, clkin,
+   return dsi_pll_calc(dpi-dsidev, clkin,
pll_min, pll_max,
dpi_calc_pll_cb, ctx);
 }
@@ -252,7 +255,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct 
dpi_clk_calc_ctx *ctx)
 
 
 
-static int dpi_set_dsi_clk(enum omap_channel channel,
+static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
 {
@@ -260,18 +263,18 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
int r;
bool ok;
 
-   ok = dpi_dsi_clk_calc(pck_req, ctx);
+   ok = dpi_dsi_clk_calc(dpi, pck_req, ctx);
if (!ok)
return -EINVAL;
 
-   r = dsi_pll_set_clock_div(dpi.dsidev, ctx.dsi_cinfo);
+   r = dsi_pll_set_clock_div(dpi-dsidev, ctx.dsi_cinfo);
if (r)
return r;
 
dss_select_lcd_clk_source(channel,
dpi_get_alt_clk_src(channel));
 
-   dpi.mgr_config.clock_info = ctx.dispc_cinfo;
+   dpi-mgr_config.clock_info = ctx.dispc_cinfo;
 
*fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
*lck_div = ctx.dispc_cinfo.lck_div;
@@ -280,8 +283,8 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
return 0;
 }
 
-static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
-   int *lck_div, int *pck_div)
+static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
+   unsigned long *fck, int *lck_div, int *pck_div)
 {
struct dpi_clk_calc_ctx ctx;
int r;
@@ -295,7 +298,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, 
unsigned long *fck,
if (r)
return r;
 
-   dpi.mgr_config.clock_info = ctx.dispc_cinfo;
+   dpi-mgr_config.clock_info = ctx.dispc_cinfo;
 
*fck = ctx.fck;
*lck_div = ctx.dispc_cinfo.lck_div;
@@ -304,19 +307,21 @@ static int dpi_set_dispc_clk(unsigned long pck_req, 
unsigned long *fck,
return 0;
 }
 
-static int dpi_set_mode(struct omap_overlay_manager *mgr)
+static int dpi_set_mode(struct dpi_data *dpi)
 {
-   struct omap_video_timings *t = dpi.timings;
+   struct omap_dss_device *out = dpi-output;
+   struct omap_overlay_manager *mgr = out-manager;
+   struct omap_video_timings *t = dpi-timings;
int lck_div = 0, pck_div = 0;
unsigned long fck = 0;
unsigned long pck;
int r = 0;
 
-   if (dpi.dsidev)
-   r = dpi_set_dsi_clk(mgr-id, t-pixelclock, fck,
+   if (dpi-dsidev)
+   r = dpi_set_dsi_clk(dpi, mgr-id, t-pixelclock, fck,
lck_div, pck_div);
else
-   r = dpi_set_dispc_clk(t-pixelclock, fck,
+   r = dpi_set_dispc_clk(dpi, t-pixelclock, fck

[PATCH v3 2/7] OMAPDSS: DPI: Allocate driver data

2014-06-04 Thread Archit Taneja
Allocate driver data(dpi_data) for each DPI instance. It's allocated in
omap_dpi_probe() when DT isn't used, and in dpi_init_port() when DT is used.
The dpi_data struct instance is no longer global. In the case of DPI ops, it's
retrieved from dpi_get_data_from_dssdev(). 'dssdev' passed by the connected
encoder/panel driver is a pointer to the 'output' member in dpi_data, and thus
can be used to get the DPI instance's driver data. In the case of probe/ini_port
functions, it's set as DPI/DSS device's private data embedded in the
platform_device struct.

Having dpi_data as private data of the platform device will not work for
multiple DPI instances in the DT case. This is because there is no corresponding
platform_device for DPI or SDI, they exist only as ports under the parent DSS
platform_device in the DT case. The DPI port's private data('data' member in
device_node struct) will later be used to store dpi_data.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c | 46 ++---
 drivers/video/fbdev/omap2/dss/dss.c |  6 ++---
 drivers/video/fbdev/omap2/dss/dss.h |  2 +-
 3 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 945d988..9087619 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -54,7 +54,15 @@ struct dpi_data {
bool port_initialized;
 };
 
-static struct dpi_data dpi;
+static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device 
*dssdev)
+{
+   return container_of(dssdev, struct dpi_data, output);
+}
+
+static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
+{
+   return dev_get_drvdata(pdev-dev);
+}
 
 static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
 {
@@ -359,7 +367,7 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi)
 
 static int dpi_display_enable(struct omap_dss_device *dssdev)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_dss_device *out = dpi-output;
int r;
 
@@ -439,7 +447,7 @@ err_no_reg:
 
 static void dpi_display_disable(struct omap_dss_device *dssdev)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_overlay_manager *mgr = dpi-output.manager;
 
mutex_lock(dpi-lock);
@@ -463,7 +471,7 @@ static void dpi_display_disable(struct omap_dss_device 
*dssdev)
 static void dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 
DSSDBG(dpi_set_timings\n);
 
@@ -477,7 +485,7 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
 static void dpi_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 
mutex_lock(dpi-lock);
 
@@ -489,7 +497,7 @@ static void dpi_get_timings(struct omap_dss_device *dssdev,
 static int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_overlay_manager *mgr = dpi-output.manager;
int lck_div, pck_div;
unsigned long fck;
@@ -529,7 +537,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
 
 static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 
mutex_lock(dpi-lock);
 
@@ -635,7 +643,7 @@ static enum omap_channel dpi_get_channel(void)
 static int dpi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_overlay_manager *mgr;
int r;
 
@@ -694,7 +702,7 @@ static const struct omapdss_dpi_ops dpi_ops = {
 
 static void dpi_init_output(struct platform_device *pdev)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
struct omap_dss_device *out = dpi-output;
 
out-dev = pdev-dev;
@@ -710,7 +718,7 @@ static void dpi_init_output(struct platform_device *pdev)
 
 static void __exit dpi_uninit_output(struct platform_device *pdev)
 {
-   struct dpi_data *dpi = dpi;
+   struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
struct omap_dss_device *out = dpi-output;
 
omapdss_unregister_output(out);
@@ -718,7 +726,11 @@ static void __exit dpi_uninit_output(struct 
platform_device *pdev)
 
 static int omap_dpi_probe(struct platform_device *pdev

[PATCH v3 5/7] OMAPDSS: DT: Get source endpoint by matching reg-id

2014-06-04 Thread Archit Taneja
In omapdss_of_find_source_for_first_ep, we retrieve a source endpoint's DT node,
and then see what omapdss output has the matching device_node pointer in
omap_dss_find_output_by_node.

For all DPI and SDI outputs, the device_node pointer is set as the parent's DSS
device_node pointer. If the source is one of these outputs, the above method
won't work.

To get the correct output for ports within DSS(and in other cases in the future,
where multiple ports might be under one device), we require additional
information which is exclusive to the output port.

We create a new field in omap_dss_device called 'port_num', this provides port
number of the output port corresponding to this device. When searching for the
source endpoint in DT, we extract the 'reg' property from the port corresponding
to the endpoint source. From the list of registered outputs, we pick out that
output which has both dev-of_node and port_num matching with the device_node
pointer and 'reg' of the source endpoint node from DT.

For encoder blocks(the ones which have both an input and output port), we need
to set the port_num as the 'reg' property for the output port as defined in the
DT bindings. We set port_num to 1 in the tfp410 and tpd12s015 encoder drivers.

Signed-off-by: Archit Taneja arc...@ti.com
---
 .../fbdev/omap2/displays-new/encoder-tfp410.c  |  1 +
 .../fbdev/omap2/displays-new/encoder-tpd12s015.c   |  1 +
 drivers/video/fbdev/omap2/dss/dss-of.c | 58 +++---
 drivers/video/fbdev/omap2/dss/dss.h|  4 ++
 drivers/video/fbdev/omap2/dss/output.c | 19 +--
 include/video/omapdss.h|  5 +-
 6 files changed, 66 insertions(+), 22 deletions(-)

diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c 
b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index b4e9a42..d927455 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
@@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev)
dssdev-output_type = OMAP_DISPLAY_TYPE_DVI;
dssdev-owner = THIS_MODULE;
dssdev-phy.dpi.data_lines = ddata-data_lines;
+   dssdev-port_num = 1;
 
r = omapdss_register_output(dssdev);
if (r) {
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c 
b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index 7e33686..9e25fe7 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -389,6 +389,7 @@ static int tpd_probe(struct platform_device *pdev)
dssdev-type = OMAP_DISPLAY_TYPE_HDMI;
dssdev-output_type = OMAP_DISPLAY_TYPE_HDMI;
dssdev-owner = THIS_MODULE;
+   dssdev-port_num = 1;
 
in = ddata-in;
 
diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c 
b/drivers/video/fbdev/omap2/dss/dss-of.c
index a4b20aa..928ee63 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -20,6 +20,8 @@
 
 #include video/omapdss.h
 
+#include dss.h
+
 struct device_node *
 omapdss_of_get_next_port(const struct device_node *parent,
 struct device_node *prev)
@@ -84,20 +86,17 @@ omapdss_of_get_next_endpoint(const struct device_node 
*parent,
 }
 EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);
 
-static struct device_node *
-omapdss_of_get_remote_device_node(const struct device_node *node)
+struct device_node *dss_of_port_get_parent_device(struct device_node *port)
 {
struct device_node *np;
int i;
 
-   np = of_parse_phandle(node, remote-endpoint, 0);
-
-   if (!np)
+   if (!port)
return NULL;
 
-   np = of_get_next_parent(np);
+   np = of_get_next_parent(port);
 
-   for (i = 0; i  3  np; ++i) {
+   for (i = 0; i  2  np; ++i) {
struct property *prop;
 
prop = of_find_property(np, compatible, NULL);
@@ -111,6 +110,31 @@ omapdss_of_get_remote_device_node(const struct device_node 
*node)
return NULL;
 }
 
+u32 dss_of_port_get_port_number(struct device_node *port)
+{
+   int r;
+   u32 reg;
+
+   r = of_property_read_u32(port, reg, reg);
+   if (r)
+   reg = 0;
+
+   return reg;
+}
+
+static struct device_node *omapdss_of_get_remote_port(const struct device_node 
*node)
+{
+   struct device_node *np;
+
+   np = of_parse_phandle(node, remote-endpoint, 0);
+   if (!np)
+   return NULL;
+
+   np = of_get_next_parent(np);
+
+   return np;
+}
+
 struct device_node *
 omapdss_of_get_first_endpoint(const struct device_node *parent)
 {
@@ -133,27 +157,25 @@ struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node)
 {
struct device_node *ep;
-   struct device_node *src_node;
+   struct device_node *src_port;
struct omap_dss_device

[PATCH v3 6/7] OMAPDSS: DPI: Add support for multiple instances

2014-06-04 Thread Archit Taneja
Register DPI outputs, and assign the port_num to them as specified by the
'reg' property in the DPI ports in DT.

To support multiple DPI instances, dpi_get_channel needs to take the DPI
instance's reg-id to get the corresponding channel. Make it take this
argument.We just pass 0 in the non-DT path, since we don't support multiple
instances in the non-DT case.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index b579022..3e204a8 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -616,7 +616,7 @@ static void dpi_init_pll(struct dpi_data *dpi)
  * the channel in some more dynamic manner, or get the channel as a user
  * parameter.
  */
-static enum omap_channel dpi_get_channel(void)
+static enum omap_channel dpi_get_channel(int reg)
 {
switch (omapdss_get_version()) {
case OMAPDSS_VER_OMAP24xx:
@@ -710,7 +710,7 @@ static void dpi_init_output(struct platform_device *pdev)
out-id = OMAP_DSS_OUTPUT_DPI;
out-output_type = OMAP_DISPLAY_TYPE_DPI;
out-name = dpi.0;
-   out-dispc_channel = dpi_get_channel();
+   out-dispc_channel = dpi_get_channel(0);
out-ops.dpi = dpi_ops;
out-owner = THIS_MODULE;
 
@@ -730,11 +730,31 @@ static void dpi_init_output_port(struct platform_device 
*pdev,
 {
struct dpi_data *dpi = port-data;
struct omap_dss_device *out = dpi-output;
+   int r;
+   u32 reg;
+
+   r = of_property_read_u32(port, reg, reg);
+   if (r)
+   reg = 0;
+
+   switch (reg) {
+   case 2:
+   out-name = dpi.2;
+   break;
+   case 1:
+   out-name = dpi.1;
+   break;
+   case 0:
+   default:
+   out-name = dpi.0;
+   break;
+   }
 
out-dev = pdev-dev;
out-id = OMAP_DSS_OUTPUT_DPI;
out-output_type = OMAP_DISPLAY_TYPE_DPI;
-   out-dispc_channel = dpi_get_channel();
+   out-dispc_channel = dpi_get_channel(reg);
+   out-port_num = reg;
out-ops.dpi = dpi_ops;
out-owner = THIS_MODULE;
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/7] OMAPDSS: Support multiple DPI instances

2014-06-04 Thread Archit Taneja
DSS on DRA7x has 3 DPI outputs. In order to get them to work. We need to make
the DPI driver support multiple DPI instances. We also need to tweak the
DT parsing done to match an encoder/connector/panel driver to find the
corresponding omapdss output. This series tries to achieve the above 2 tasks.

Changes in v3:

- Make indexes in port lists not depend on DPI and SDI CONFIGs.
- Cleaner code in dss_init_ports/uninit_ports.
- Split up the patch which creates multi DPI instances.
- Switch to a simpler way of extracting DPI driver data from dssdev.
- Change some of the dss-of fucntions, such that
  omapdss_of_find_source_for_first_ep is simplified.

Archit Taneja (7):
  OMAPDSS: DPI: Use DPI driver data
  OMAPDSS: DPI: Allocate driver data
  OMAPDSS: DPI: Store dpi_data pointer in the DT port's data
  OMAPDSS: DSS: init dss ports cleanly
  OMAPDSS: DT: Get source endpoint by matching reg-id
  OMAPDSS: DPI: Add support for multiple instances
  omapdss: DSS: add reg-id param to dpi_select_source

 .../fbdev/omap2/displays-new/encoder-tfp410.c  |   1 +
 .../fbdev/omap2/displays-new/encoder-tpd12s015.c   |   1 +
 drivers/video/fbdev/omap2/dss/dpi.c| 259 ++---
 drivers/video/fbdev/omap2/dss/dss-of.c |  58 +++--
 drivers/video/fbdev/omap2/dss/dss.c| 108 +++--
 drivers/video/fbdev/omap2/dss/dss.h|  34 ++-
 drivers/video/fbdev/omap2/dss/output.c |  19 +-
 drivers/video/fbdev/omap2/dss/sdi.c|   2 +-
 include/video/omapdss.h|   5 +-
 9 files changed, 354 insertions(+), 133 deletions(-)

-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/7] OMAPDSS: DSS: init dss ports cleanly

2014-06-04 Thread Archit Taneja
The init/uninit port functions are used to set up the DPI and SDI outputs under
the dss platform device. A 'reg' property is used to determine whether the node
is DPI or SDI for OMAP34xx DSS revision. For other DSS revisions, only DPI
output exists.

For multiple DPI output instances(introduced in DRA7xx DSS), we would use the
'reg' property in dts to specify the DPI output instance.

The current functions work fine if there is only one DPI output instance in
DSS. For multiple DPI instances, it would get complicated to figure out whether
'reg' is used to specify whether the output is SDI, or another DPI instance.

We create a list of port types supported for each DSS rev, with the index of the
port in the list matching the reg id. This allows us to have a more generic way
to init/uninit ports within DSS, and support multiple DPI ports.

Also, make the uninit_port functions iterative since we will have multiple DPI
ports to uninit in the future.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dss.c | 81 ++---
 drivers/video/fbdev/omap2/dss/dss.h | 26 +++-
 drivers/video/fbdev/omap2/dss/sdi.c |  2 +-
 3 files changed, 93 insertions(+), 16 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index bebb824..3b41953 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -70,6 +70,8 @@ struct dss_features {
u8 fck_div_max;
u8 dss_fck_multiplier;
const char *parent_clk_name;
+   enum omap_display_type *ports;
+   int num_ports;
int (*dpi_select_source)(enum omap_channel channel);
 };
 
@@ -689,6 +691,16 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+
+static enum omap_display_type omap2plus_ports[] = {
+   OMAP_DISPLAY_TYPE_DPI,
+};
+
+static enum omap_display_type omap34xx_ports[] = {
+   OMAP_DISPLAY_TYPE_DPI,
+   OMAP_DISPLAY_TYPE_SDI,
+};
+
 static const struct dss_features omap24xx_dss_feats __initconst = {
/*
 * fck div max is really 16, but the divider range has gaps. The range
@@ -698,6 +710,8 @@ static const struct dss_features omap24xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   2,
.parent_clk_name=   core_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static const struct dss_features omap34xx_dss_feats __initconst = {
@@ -705,6 +719,8 @@ static const struct dss_features omap34xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   2,
.parent_clk_name=   dpll4_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap34xx_ports,
+   .num_ports  =   ARRAY_SIZE(omap34xx_ports),
 };
 
 static const struct dss_features omap3630_dss_feats __initconst = {
@@ -712,6 +728,8 @@ static const struct dss_features omap3630_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll4_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static const struct dss_features omap44xx_dss_feats __initconst = {
@@ -719,6 +737,8 @@ static const struct dss_features omap44xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll_per_x2_ck,
.dpi_select_source  =   dss_dpi_select_source_omap4,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static const struct dss_features omap54xx_dss_feats __initconst = {
@@ -726,6 +746,8 @@ static const struct dss_features omap54xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll_per_x2_ck,
.dpi_select_source  =   dss_dpi_select_source_omap5,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static const struct dss_features am43xx_dss_feats __initconst = {
@@ -733,6 +755,8 @@ static const struct dss_features am43xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   0,
.parent_clk_name=   NULL,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static int __init dss_init_features(struct platform_device *pdev)
@@ -798,23 +822,32 @@ static int __init dss_init_ports(struct platform_device 
*pdev)
if (!port

[PATCH v3 7/7] omapdss: DSS: add reg-id param to dpi_select_source

2014-06-04 Thread Archit Taneja
Add an argument which describes which DPI instance we are referring to when
selecting it's overlay manager.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c |  2 +-
 drivers/video/fbdev/omap2/dss/dss.c | 12 ++--
 drivers/video/fbdev/omap2/dss/dss.h |  2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 3e204a8..776c409 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -396,7 +396,7 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
if (r)
goto err_get_dispc;
 
-   r = dss_dpi_select_source(out-manager-id);
+   r = dss_dpi_select_source(out-port_num, out-manager-id);
if (r)
goto err_src_sel;
 
diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index 3b41953..8fd141f 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -72,7 +72,7 @@ struct dss_features {
const char *parent_clk_name;
enum omap_display_type *ports;
int num_ports;
-   int (*dpi_select_source)(enum omap_channel channel);
+   int (*dpi_select_source)(int id, enum omap_channel channel);
 };
 
 static struct {
@@ -566,7 +566,7 @@ enum dss_hdmi_venc_clk_source_select 
dss_get_hdmi_venc_clk_source(void)
return REG_GET(DSS_CONTROL, 15, 15);
 }
 
-static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
+static int dss_dpi_select_source_omap2_omap3(int id, enum omap_channel channel)
 {
if (channel != OMAP_DSS_CHANNEL_LCD)
return -EINVAL;
@@ -574,7 +574,7 @@ static int dss_dpi_select_source_omap2_omap3(enum 
omap_channel channel)
return 0;
 }
 
-static int dss_dpi_select_source_omap4(enum omap_channel channel)
+static int dss_dpi_select_source_omap4(int id, enum omap_channel channel)
 {
int val;
 
@@ -594,7 +594,7 @@ static int dss_dpi_select_source_omap4(enum omap_channel 
channel)
return 0;
 }
 
-static int dss_dpi_select_source_omap5(enum omap_channel channel)
+static int dss_dpi_select_source_omap5(int id, enum omap_channel channel)
 {
int val;
 
@@ -620,9 +620,9 @@ static int dss_dpi_select_source_omap5(enum omap_channel 
channel)
return 0;
 }
 
-int dss_dpi_select_source(enum omap_channel channel)
+int dss_dpi_select_source(int id, enum omap_channel channel)
 {
-   return dss.feat-dpi_select_source(channel);
+   return dss.feat-dpi_select_source(id, channel);
 }
 
 static int dss_get_clocks(void)
diff --git a/drivers/video/fbdev/omap2/dss/dss.h 
b/drivers/video/fbdev/omap2/dss/dss.h
index 849ede1..a7a0d8a 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -209,7 +209,7 @@ int dss_init_platform_driver(void) __init;
 void dss_uninit_platform_driver(void);
 
 unsigned long dss_get_dispc_clk_rate(void);
-int dss_dpi_select_source(enum omap_channel channel);
+int dss_dpi_select_source(int id, enum omap_channel channel);
 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 3/6] ARM: OMAP2+: Add CONTROL_MODULE_CORE as a clock provider for DRA7x

2014-05-28 Thread Archit Taneja
In DRA7x SoCs, the CONTROL_MODULE_CORE sub block in the control module has a
few register fields which perform gating or muxing of clocks.

These gate/muxes are generally SoC level clocks entering an IP, which didn't
manage to make it in the clock management related registers for the IP.

Other OMAP SOCs don't seem to have clock related register fields in the control
module.

We create a new table and function to init ctrl-core IPS as clock providers.
This, along with scrm clock providers, are initialized in of_control_init().
We add a compatible string for dra7-ctrl-core in the DT match table.

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/mach-omap2/control.c | 22 +-
 arch/arm/mach-omap2/control.h |  2 +-
 arch/arm/mach-omap2/io.c  |  2 +-
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 12cd736..d9567bc 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -592,7 +592,27 @@ static struct of_device_id omap_scrm_dt_match_table[] = {
{ }
 };
 
-int __init of_scrm_init(void)
+static int __init of_scrm_init(void)
 {
return of_prcm_module_init(omap_scrm_dt_match_table);
 }
+
+static struct of_device_id omap_ctrl_core_dt_match_table[] = {
+   { .compatible = ti,dra7-ctrl-core },
+   { }
+};
+
+static int __init of_ctrl_core_init(void)
+{
+   return of_prcm_module_init(omap_ctrl_core_dt_match_table);
+}
+
+int __init of_control_init(void)
+{
+   int ret;
+
+   ret = of_scrm_init();
+   ret |= of_ctrl_core_init();
+
+   return ret;
+}
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index 5d695f1..405979e 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -428,7 +428,7 @@ extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode);
 extern void omap3630_ctrl_disable_rta(void);
 extern int omap3_ctrl_save_padconf(void);
 extern void omap3_ctrl_set_iva_bootmode_idle(void);
-int of_scrm_init(void);
+int of_control_init(void);
 extern void omap2_set_globals_control(void __iomem *ctrl,
  void __iomem *ctrl_pad);
 #else
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index c78e2b8..49e344b 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -725,7 +725,7 @@ int __init omap_clk_init(void)
if (!omap_clk_soc_init)
return 0;
 
-   ret = of_scrm_init();
+   ret = of_control_init();
if (ret)
return ret;
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 5/6] ARM: dts: Add dss_deshdcp clock node under dra7-ctrl-core

2014-05-28 Thread Archit Taneja
The DESHDCP clock is required only by the DES-HDCP block within HDMI in DSS.
However, if the clock isn't set before DSS clock domian is enabled, the clock
domain never comes out of idle state.

The DESHDCP clock is enabled/disabled at the DSS boundary by the bit
DSS_DESHDCP_CLKEN in CTRL_CORE_CONTROL_IO_2.

Add dss_deshdcp gate-clock node under dra7-ctrl-core. There are separate bit
fields for enabling and disabling the clock. We just map the enable bit since
this clock doesn't cause any impact if left enabled.

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/boot/dts/dra7xx-clocks.dtsi | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi 
b/arch/arm/boot/dts/dra7xx-clocks.dtsi
index cfb8fc7..a1653ba 100644
--- a/arch/arm/boot/dts/dra7xx-clocks.dtsi
+++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi
@@ -2007,6 +2007,16 @@
};
 };
 
+ctrl_core_clocks {
+   dss_deshdcp_clk: dss_deshdcp_clk {
+   #clock-cells = 0;
+   compatible = ti,gate-clock;
+   clocks = l3_iclk_div;
+   ti,bit-shift = 0;
+   reg = 0x0558;
+   };
+};
+
 cm_core_clockdomains {
coreaon_clkdm: coreaon_clkdm {
compatible = ti,clockdomain;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 6/6] CLK: TI: Enable dss_deshdcp clock in dra7xx_clk_init

2014-05-28 Thread Archit Taneja
The DESHDCP clock is required only by the DES-HDCP block within HDMI in DSS.
However, if the clock isn't set before DSS clock domian is enabled, the clock
domain never comes out of idle state.

This is because the DSS IP is designed in such a way that if DES-HDCP block
can't transition from idle state, the entire DSS clock domain also cannot
transition from idle to enabled. DES-HDCP block needs the DESHDCP clock
enabled to transition from idle successfully.

We enable the deshdcp clock in dra7xx_clk_init() which happens before omap
hwmods are setup. This clock is effectively a gate clock with the parent as
DSS_L3_GICLK. The parent is an automatically controlled clock by DSS clock
domain and hence doesn't have a clock node associated to it. Since
DSS_L3_GICLK is derived from the OCP clock, we set the dss_deshdcp_clk's
parent as l3_iclk_div.

Leaving this bit enabled doesn't prevent DSS or the system to suspend, and only
a very few flops get this clock all the time. So there is negligible impact.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/clk/ti/clk-7xx.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c
index f7e4073..3f73a02 100644
--- a/drivers/clk/ti/clk-7xx.c
+++ b/drivers/clk/ti/clk-7xx.c
@@ -179,6 +179,7 @@ static struct ti_dt_clk dra7xx_clks[] = {
DT_CLK(NULL, dss_hdmi_clk, dss_hdmi_clk),
DT_CLK(NULL, dss_video1_clk, dss_video1_clk),
DT_CLK(NULL, dss_video2_clk, dss_video2_clk),
+   DT_CLK(NULL, dss_deshdcp_clk, dss_deshdcp_clk),
DT_CLK(NULL, gpio1_dbclk, gpio1_dbclk),
DT_CLK(NULL, gpio2_dbclk, gpio2_dbclk),
DT_CLK(NULL, gpio3_dbclk, gpio3_dbclk),
@@ -306,7 +307,7 @@ static struct ti_dt_clk dra7xx_clks[] = {
 int __init dra7xx_dt_clk_init(void)
 {
int rc;
-   struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck;
+   struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *dss_deshdcp_ck;
 
ti_dt_clocks_register(dra7xx_clks);
 
@@ -327,5 +328,10 @@ int __init dra7xx_dt_clk_init(void)
if (rc)
pr_err(%s: failed to configure GMAC DPLL!\n, __func__);
 
+   dss_deshdcp_ck = clk_get_sys(NULL, dss_deshdcp_clk);
+   rc = clk_prepare_enable(dss_deshdcp_ck);
+   if (rc)
+   pr_err(%s: failed to enable DESHDCP clock\n, __func__);
+
return rc;
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 4/6] ARM: dts: Add ctrl-core DT node for DRA7

2014-05-28 Thread Archit Taneja
Add DT node for the ctrl-core sub module of the DRA7 control module. We map the
CTRL_MODULE_CORE address region up to 0x4a002d60, this region contains register
fields which configure clocks. The remainder of the registers are related to
pad configurations or cross-bar configurations, and therefore aren't mapped.

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/boot/dts/dra7.dtsi | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 149b550..14d1905 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -148,6 +148,19 @@
};
};
 
+   ctrl_core: ctrl_core@4a002000 {
+   compatible = ti,dra7-ctrl-core;
+   reg = 0x4a002000 0x6d0;
+
+   ctrl_core_clocks: clocks {
+   #address-cells = 1;
+   #size-cells = 0;
+   };
+
+   ctrl_core_clockdomains: clockdomains {
+   };
+   };
+
counter32k: counter@4ae04000 {
compatible = ti,omap-counter32k;
reg = 0x4ae04000 0x40;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 1/6] CLK: TI: clockdomain: add support for retrying init

2014-05-28 Thread Archit Taneja
From: Tero Kristo t-kri...@ti.com

Retry init is needed if clockdomains are registered before the corresponding
clocks are ready. In this case, the clockdomain info is added to a list
which will be processed once the clockdomains for next PRCM module are
processed.

Signed-off-by: Tero Kristo t-kri...@ti.com
---
 arch/arm/mach-omap2/prm_common.c |  3 +-
 drivers/clk/ti/clockdomain.c | 77 ++--
 include/linux/clk/ti.h   |  2 +-
 3 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index b4c4ab9..56462af 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -523,10 +523,9 @@ int __init of_prcm_init(void)
mem = of_iomap(np, 0);
clk_memmaps[memmap_index] = mem;
ti_dt_clk_init_provider(np, memmap_index);
+   ti_dt_clockdomains_setup(np);
memmap_index++;
}
 
-   ti_dt_clockdomains_setup();
-
return 0;
 }
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index f1e0038..29fa543 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -24,26 +24,60 @@
 #undef pr_fmt
 #define pr_fmt(fmt) %s:  fmt, __func__
 
-static void __init of_ti_clockdomain_setup(struct device_node *node)
+struct clkdm_init_item {
+   struct device_node *node;
+   int index;
+   struct list_head link;
+};
+
+static LIST_HEAD(retry_list);
+
+static int of_ti_init_clk_clkdm(struct device_node *node, int index)
 {
struct clk *clk;
struct clk_hw *clk_hw;
-   const char *clkdm_name = node-name;
+
+   clk = of_clk_get(node, index);
+
+   if (IS_ERR_OR_NULL(clk)) {
+   pr_debug(%s[%d] = %08x\n, node-name, index, (u32)clk);
+   return -EBUSY;
+   }
+
+   if (__clk_get_flags(clk)  CLK_IS_BASIC) {
+   pr_warn(can't setup clkdm for basic clk %s\n,
+   __clk_get_name(clk));
+   return -EINVAL;
+   }
+
+   clk_hw = __clk_get_hw(clk);
+   to_clk_hw_omap(clk_hw)-clkdm_name = node-name;
+   omap2_init_clk_clkdm(clk_hw);
+
+   return 0;
+}
+
+static void __init of_ti_clockdomain_setup(struct device_node *node)
+{
int i;
int num_clks;
+   struct clkdm_init_item *retry;
+   int ret;
 
num_clks = of_count_phandle_with_args(node, clocks, #clock-cells);
 
for (i = 0; i  num_clks; i++) {
-   clk = of_clk_get(node, i);
-   if (__clk_get_flags(clk)  CLK_IS_BASIC) {
-   pr_warn(can't setup clkdm for basic clk %s\n,
-   __clk_get_name(clk));
+   ret = of_ti_init_clk_clkdm(node, i);
+
+   if (ret == -EBUSY) {
+   retry = kzalloc(sizeof(*retry), GFP_KERNEL);
+   if (!retry)
+   return;
+   retry-node = node;
+   retry-index = i;
+   list_add(retry-link, retry_list);
continue;
}
-   clk_hw = __clk_get_hw(clk);
-   to_clk_hw_omap(clk_hw)-clkdm_name = clkdm_name;
-   omap2_init_clk_clkdm(clk_hw);
}
 }
 
@@ -61,10 +95,31 @@ static struct of_device_id ti_clkdm_match_table[] 
__initdata = {
  * called after rest of the DT clock init has completed and all
  * clock nodes have been registered.
  */
-void __init ti_dt_clockdomains_setup(void)
+void __init ti_dt_clockdomains_setup(struct device_node *node)
 {
struct device_node *np;
-   for_each_matching_node(np, ti_clkdm_match_table) {
+   struct device_node *clkdms;
+   struct clkdm_init_item *retry, *tmp;
+   int ret;
+
+   clkdms = of_get_child_by_name(node, clockdomains);
+   if (!clkdms)
+   return;
+
+   list_for_each_entry_safe(retry, tmp, retry_list, link) {
+   pr_debug(retry-init: %s [%d]\n, retry-node-name,
+retry-index);
+   ret = of_ti_init_clk_clkdm(retry-node, retry-index);
+   if (!ret) {
+   list_del(retry-link);
+   kfree(retry);
+   }
+   }
+
+   for_each_child_of_node(clkdms, np) {
+   if (!of_match_node(ti_clkdm_match_table, np))
+   continue;
+
of_ti_clockdomain_setup(np);
}
 }
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 4a21a87..20dd7c0 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -263,7 +263,7 @@ void omap3_clk_lock_dpll5(void);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 void ti_dt_clk_init_provider(struct device_node *np, int index);
-void ti_dt_clockdomains_setup(void);
+void 

[RFC v2 0/6] ARM: dts: Add a new clk provider, and implement dss_deshdcp clock with it

2014-05-28 Thread Archit Taneja
This series tries to create CONTROL_MODULE_CORE as a new clock provider, and
create a clock using it required by DSS on DRA7.

The previous revision of the series added the new clock provider within prcm
driver code itself. Suggestions were made by Paul and Tero to move it to control
module driver code.

I picked up 2 patches from Tero's WIP branch below, and added DRA7's control
module core block as a clock provider. The DSS_DESHDCP clock is easy to
implement after that.

https://github.com/t-kristo/linux-pm/tree/3.14-rc4-cm-prm-driver-wip 

Archit Taneja (5):
  ARM: PRCM: split PRCM module init to their own driver files
  ARM: OMAP2+: Add CONTROL_MODULE_CORE as a clock provider for DRA7x
  ARM: dts: Add ctrl-core DT node for DRA7
  ARM: dts: Add dss_deshdcp clock node under dra7-ctrl-core
  CLK: TI: Enable dss_deshdcp clock in dra7xx_clk_init

Tero Kristo (1):
  CLK: TI: clockdomain: add support for retrying init

 arch/arm/boot/dts/dra7.dtsi  | 13 ++
 arch/arm/boot/dts/dra7xx-clocks.dtsi | 10 +
 arch/arm/mach-omap2/cm_common.c  | 18 +
 arch/arm/mach-omap2/control.c| 35 
 arch/arm/mach-omap2/control.h|  1 +
 arch/arm/mach-omap2/io.c |  4 ++
 arch/arm/mach-omap2/prcm-common.h|  5 +++
 arch/arm/mach-omap2/prm_common.c | 55 +++---
 drivers/clk/ti/clk-7xx.c |  8 +++-
 drivers/clk/ti/clockdomain.c | 77 ++--
 include/linux/clk/ti.h   |  2 +-
 11 files changed, 192 insertions(+), 36 deletions(-)

-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 2/6] ARM: PRCM: split PRCM module init to their own driver files

2014-05-28 Thread Archit Taneja
Currently, clock providers coming from CM, PRM, and SCRM are all initialized in
prm_common.c.

Move the DT-match tables to their respective files, and create separate init
functions for each module.

Originally worked on by: Tero Kristo t-kri...@ti.com

Cc: Tero Kristo t-kri...@ti.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/mach-omap2/cm_common.c   | 18 ++
 arch/arm/mach-omap2/control.c | 15 +++
 arch/arm/mach-omap2/control.h |  1 +
 arch/arm/mach-omap2/io.c  |  4 +++
 arch/arm/mach-omap2/prcm-common.h |  5 
 arch/arm/mach-omap2/prm_common.c  | 52 +++
 6 files changed, 74 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c
index 40b3b5a..8506990 100644
--- a/arch/arm/mach-omap2/cm_common.c
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -14,6 +14,7 @@
 #include linux/kernel.h
 #include linux/init.h
 #include linux/errno.h
+#include linux/of.h
 
 #include cm2xxx.h
 #include cm3xxx.h
@@ -138,3 +139,20 @@ int cm_unregister(struct cm_ll_data *cld)
 
return 0;
 }
+
+static struct of_device_id omap_cm_dt_match_table[] = {
+   { .compatible = ti,omap3-cm },
+   { .compatible = ti,omap4-cm1 },
+   { .compatible = ti,omap4-cm2 },
+   { .compatible = ti,omap5-cm-core-aon },
+   { .compatible = ti,omap5-cm-core },
+   { .compatible = ti,dra7-cm-core-aon },
+   { .compatible = ti,dra7-cm-core },
+   { }
+};
+
+
+int __init of_cm_init(void)
+{
+   return of_prcm_module_init(omap_cm_dt_match_table);
+}
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 44bb4d5..12cd736 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -581,3 +581,18 @@ void omap3_ctrl_set_iva_bootmode_idle(void)
 OMAP343X_CONTROL_IVA2_BOOTMOD);
 }
 #endif /* CONFIG_ARCH_OMAP3  CONFIG_PM */
+
+static struct of_device_id omap_scrm_dt_match_table[] = {
+   { .compatible = ti,am3-scrm },
+   { .compatible = ti,am4-scrm },
+   { .compatible = ti,omap2-scrm },
+   { .compatible = ti,omap3-scrm },
+   { .compatible = ti,omap4-scrm },
+   { .compatible = ti,omap5-scrm },
+   { }
+};
+
+int __init of_scrm_init(void)
+{
+   return of_prcm_module_init(omap_scrm_dt_match_table);
+}
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index da05480..5d695f1 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -428,6 +428,7 @@ extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode);
 extern void omap3630_ctrl_disable_rta(void);
 extern int omap3_ctrl_save_padconf(void);
 extern void omap3_ctrl_set_iva_bootmode_idle(void);
+int of_scrm_init(void);
 extern void omap2_set_globals_control(void __iomem *ctrl,
  void __iomem *ctrl_pad);
 #else
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index f14f9ac..c78e2b8 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -725,6 +725,10 @@ int __init omap_clk_init(void)
if (!omap_clk_soc_init)
return 0;
 
+   ret = of_scrm_init();
+   if (ret)
+   return ret;
+
ret = of_prcm_init();
if (!ret)
ret = omap_clk_soc_init();
diff --git a/arch/arm/mach-omap2/prcm-common.h 
b/arch/arm/mach-omap2/prcm-common.h
index 0e841fd..a68d98e 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -493,6 +493,8 @@ struct omap_prcm_irq_setup {
.priority = _priority   \
}
 
+struct of_device_id;
+
 extern void omap_prcm_irq_cleanup(void);
 extern int omap_prcm_register_chain_handler(
struct omap_prcm_irq_setup *irq_setup);
@@ -500,6 +502,9 @@ extern int omap_prcm_event_to_irq(const char *event);
 extern void omap_prcm_irq_prepare(void);
 extern void omap_prcm_irq_complete(void);
 
+int of_prcm_module_init(struct of_device_id *match_table);
+int of_cm_init(void);
+
 # endif
 
 #endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 56462af..85fc9f9 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -470,25 +470,18 @@ int prm_unregister(struct prm_ll_data *pld)
return 0;
 }
 
-static struct of_device_id omap_prcm_dt_match_table[] = {
-   { .compatible = ti,am3-prcm },
-   { .compatible = ti,am3-scrm },
-   { .compatible = ti,am4-prcm },
-   { .compatible = ti,am4-scrm },
+static struct of_device_id omap_prm_dt_match_table[] = {
{ .compatible = ti,omap3-prm },
-   { .compatible = ti,omap3-cm },
-   { .compatible = ti,omap3-scrm },
-   { .compatible = ti,omap4-cm1 },
{ .compatible = ti,omap4-prm },
-   { .compatible = ti,omap4-cm2 },
-   { .compatible = ti,omap4-scrm },
{ .compatible = ti,omap5-prm },
-   { .compatible = ti,omap5-cm

Re: [RFC v2 3/5] OMAPDSS: DPI: support multiple DPI instances

2014-05-27 Thread Archit Taneja

On Tuesday 27 May 2014 02:34 PM, Tomi Valkeinen wrote:

On 26/05/14 12:28, Archit Taneja wrote:

SoCs containing DSS until now had only one DPI instance. DRA7x has 3 DPI
instances.

In order to support multiple instances, we allocate a driver data
struct(dpi_data) for each instance. This is somewhat similar to how DSI driver
was changed to support multiple instances.

One difference is that there aren't platform devices for each DPI instance
when DT is used. In the DT case, we store the dpi_data pointer in the DPI port's
(of the type struct device_node) data pointer. In the non DT case, we still
have dummy platform devices, and the device's private data pointer is used to
store the DPI instance's dpi_data.

dpi_init_output/dpi_uninit_output are untouched and only used for non DT case,
dpi_init_output_port/dpi_uninit_output_port are used in the DT case, where DSS
configures the ports using dpi_init_port/dpi_uninit_port.


This is a bit too big patch, I think it should be split.

The first patch could add the name to the struct dpi_data, but still
keep it static, and also change the functions to pass the dpi_data
pointer around, as you do in this patch.

The functions where you do

struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);

could just do

struct dpi_data *dpi = dpi;

This way the in the first patch you can do most of the bulk changes,
without actually changing the behavior in any way.

In the next patch, you could then add the actual support for allocating
the dpi_data instances.

Those two patches should be moved to the beginning of the series, as
they are just preparatory patches, and they don't actually change
anything with DPI.

Third DPI patch would then add support for the actual multiple DPI
instances.


Okay, that sounds like a good way to split it.




Signed-off-by: Archit Taneja arc...@ti.com
---
  drivers/video/fbdev/omap2/dss/dpi.c | 263 +---
  1 file changed, 181 insertions(+), 82 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 8593567..43966a7 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -37,7 +37,7 @@
  #include dss.h
  #include dss_features.h

-static struct {
+struct dpi_data {
struct platform_device *pdev;

struct regulator *vdds_dsi_reg;
@@ -52,7 +52,27 @@ static struct {
struct omap_dss_device output;

bool port_initialized;
-} dpi;
+};
+
+static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device 
*dssdev)
+{
+   struct device_node *parent = dssdev-dev-of_node;
+
+   /* non DT */
+   if (!parent) {
+   struct omap_dss_device *out = dssdev-src;
+
+   return dev_get_drvdata(out-dev);
+   }


Why do you need the above? Just plain container_of() below should work
for both DT and non-DT.


Yeah, that's right. For some reason I thought that dssdev in the non-DT 
case is the pointer for the next device in the chain, and not the output 
itself. I'll remove this piece.


Thanks,
Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2 2/5] OMAPDSS: DT: Get source endpoint by matching reg-id

2014-05-27 Thread Archit Taneja

On Tuesday 27 May 2014 02:04 PM, Tomi Valkeinen wrote:

On 26/05/14 12:28, Archit Taneja wrote:

In omapdss_of_find_source_for_first_ep, we retrieve a source endpoint's DT node,
and then see what omapdss output has the matching device_node pointer in
omap_dss_find_output_by_node.

For all DPI and SDI outputs, the device_node pointer is set as the parent's DSS
device_node pointer. If the source is one of these outputs, the above method
won't work.

To get the correct output for ports within DSS(and in other cases in the future,
where multiple ports might be under one device), we require additional
information which is exclusive to the output port.

We create a new field in omap_dss_device called 'port_num', this provides port
number of the output port corresponding to this device. When searching for the
source endpoint in DT, we extract the 'reg' property from the port corresponding
to the endpoint source. From the list of registered outputs, we pick out that
output which has both dev-of_node and port_num matching with the device_node
pointer and 'reg' of the source endpoint node from DT.

For encoder blocks(the ones which have both an input and output port), we need
to set the port_num as the 'reg' property for the output port as defined in the
DT bindings. We set port_num to 1 in the tfp410 and tpd12s015 encoder drivers.

Signed-off-by: Archit Taneja arc...@ti.com
---
  .../fbdev/omap2/displays-new/encoder-tfp410.c  |  1 +
  .../fbdev/omap2/displays-new/encoder-tpd12s015.c   |  1 +
  drivers/video/fbdev/omap2/dss/dss-of.c | 51 +-
  drivers/video/fbdev/omap2/dss/output.c |  8 ++--
  include/video/omapdss.h|  7 ++-
  5 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c 
b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index b4e9a42..d927455 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
@@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev)
dssdev-output_type = OMAP_DISPLAY_TYPE_DVI;
dssdev-owner = THIS_MODULE;
dssdev-phy.dpi.data_lines = ddata-data_lines;
+   dssdev-port_num = 1;

r = omapdss_register_output(dssdev);
if (r) {
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c 
b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index 7e33686..9e25fe7 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -389,6 +389,7 @@ static int tpd_probe(struct platform_device *pdev)
dssdev-type = OMAP_DISPLAY_TYPE_HDMI;
dssdev-output_type = OMAP_DISPLAY_TYPE_HDMI;
dssdev-owner = THIS_MODULE;
+   dssdev-port_num = 1;

in = ddata-in;

diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c 
b/drivers/video/fbdev/omap2/dss/dss-of.c
index a4b20aa..8ba43faa 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -132,28 +132,55 @@ EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
  struct omap_dss_device *
  omapdss_of_find_source_for_first_ep(struct device_node *node)
  {
-   struct device_node *ep;
-   struct device_node *src_node;
+   struct device_node *ep, *port_ep;
+   struct device_node *src_node, *src_port;
struct omap_dss_device *src;
+   int r;
+   u32 reg;

ep = omapdss_of_get_first_endpoint(node);
-   if (!ep)
-   return ERR_PTR(-EINVAL);
+   if (!ep) {
+   r = -EINVAL;
+   goto err_first_ep;
+   }

src_node = omapdss_of_get_remote_device_node(ep);
+   if (!src_node) {
+   r = -EINVAL;
+   goto err_src_node;
+   }

-   of_node_put(ep);
-
-   if (!src_node)
-   return ERR_PTR(-EINVAL);
+   port_ep = of_parse_phandle(ep, remote-endpoint, 0);
+   if (!port_ep) {
+   r = -EINVAL;
+   goto err_port_ep;
+   }

-   src = omap_dss_find_output_by_node(src_node);
+   src_port = of_get_next_parent(port_ep);
+   if (!src_port) {
+   r = -EINVAL;
+   goto err_src_port;
+   }

-   of_node_put(src_node);
+   r = of_property_read_u32(src_port, reg, reg);
+   if (r) {
+   r = 0;
+   reg = 0;
+   }

+   src = omap_dss_find_output_by_node_and_reg(src_node, reg);
if (!src)
-   return ERR_PTR(-EPROBE_DEFER);
+   r = -EPROBE_DEFER;


Hmm, maybe the above function, and the helper functions, should be
changed a bit more, so that this function would do:

ep = omapdss_of_get_first_endpoint(node);
src_port = omapdss_of_get_remote_port(ep);
src = omap_dss_find_output_by_port_node(src_port);


src_port will be just on level up(the parent node), the source node

Re: [RFC 1/2] ARM: OMAP2+: hwmod: Add refcounting for modulemode shared by multiple hwmods

2014-05-27 Thread Archit Taneja

Hi,

On Tuesday 27 May 2014 03:50 PM, Rajendra Nayak wrote:

On Monday 26 May 2014 04:14 PM, Archit Taneja wrote:

Generally, IP blocks/modules within a clock domain each have their own
CM_x_CLKCTRL register, each having it's own MODULEMODE field to manage the
module.

snip


@@ -2751,6 +2820,13 @@ static int __init _register(struct omap_hwmod *oh)
if (_lookup(oh-name))
return -EEXIST;

+   if (oh-prcm.omap4.flags  HWMOD_OMAP4_MODULEMODE_SHARED 
+   !oh-prcm.omap4.modulemode_ref) {


You might also want to check for someone populating a modulemode_ref but
failing to populate the flag?

Alternatively, Since you expect a modulemode_ref to be always available for all 
modules which
share modulemode, that in itself can be used to identify such modules without 
the
need of an additional flag?


It does seem redundant to have a flag at the moment. But the flag make 
things more visible. 'prcm.omap4.modulemode' seems to work without a 
flag too, so I suppose I'll remove the flag.





+   pr_err(omap_hwmod: %s shares modulemode, but doesn't hold a ref to 
it\n,
+   oh-name);
+   return -EINVAL;
+   }
+
list_add_tail(oh-node, omap_hwmod_list);

INIT_LIST_HEAD(oh-master_ports);
@@ -2759,6 +2835,15 @@ static int __init _register(struct omap_hwmod *oh)

oh-_state = _HWMOD_STATE_REGISTERED;

+   if (oh-prcm.omap4.flags  HWMOD_OMAP4_MODULEMODE_SHARED) {
+   struct modulemode_shared *mmode = oh-prcm.omap4.modulemode_ref;
+
+   if (!mmode-registered) {
+   spin_lock_init(mmode-lock);
+   mmode-registered = true;


If this is only used to keep track of the spin_lock being initialized, maybe 
it'll be
more readable if you just call it mmode-spin_lock_init = true.


Yes, I'll fix this.

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2 2/5] OMAPDSS: DT: Get source endpoint by matching reg-id

2014-05-27 Thread Archit Taneja

On Tuesday 27 May 2014 03:54 PM, Tomi Valkeinen wrote:

On 27/05/14 12:49, Archit Taneja wrote:

On Tuesday 27 May 2014 02:04 PM, Tomi Valkeinen wrote:



Hmm, maybe the above function, and the helper functions, should be
changed a bit more, so that this function would do:

ep = omapdss_of_get_first_endpoint(node);
src_port = omapdss_of_get_remote_port(ep);
src = omap_dss_find_output_by_port_node(src_port);


src_port will be just on level up(the parent node), the source node will
be still a couple of hops up.

Getting the source node would require us to do some DT related hopping
in omap_dss_find_output_by_port_node(). And it'll also require parsing
of the dss output_list in output.c. I'm worried it'll be a bit messy,
and we might end up adding some DT parsing in output.c


But now the function above is messy =).

Well, I haven't thought what the code would actually be. I just thought
the functions I wrote would be logical in this context. As the output
omap_dss_device more or less is a port, it would feel logical to ask
for the omap_dss_device by giving the port node.

But you're right, the function in output.c would need to do a bit more
than now. Then again, we could add helper functions to dss-of.c, so that
output.c wouldn't need to do them manually.

I guess the helper funcs in this case would be:

struct device_node *dss_of_port_get_parent_device(struct device_node *port);

int dss_of_port_get_port_number(struct device_node *port);


These look fine. I'll update the patch.

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2 1/5] OMAPDSS: DSS: init dss ports cleanly

2014-05-27 Thread Archit Taneja

On Tuesday 27 May 2014 01:54 PM, Tomi Valkeinen wrote:

On 26/05/14 12:28, Archit Taneja wrote:

The init/uninit port functions are used to set up the DPI and SDI outputs under
the dss platform device. A 'reg' property is used to determine whether the node
is DPI or SDI for OMAP34xx DSS revision. For other DSS revisions, only DPI
output exists.

For multiple DPI output instances(introduced in DRA7xx DSS), we would use the
'reg' property in dts to specify the DPI output instance.

The current functions work fine if there is only one DPI output instance in
DSS. For multiple DPI instances, it would get complicated to figure out whether
'reg' is used to specify whether the output is SDI, or another DPI instance.

We create a list of port types supported for each DSS rev, with the index of the
port in the list matching the reg id. This allows us to have a more generic way
to init/uninit ports within DSS, and support multiple DPI ports.

Also, make the uninit_port functions iterative since we will have multiple DPI
ports to uninit in the future.

Signed-off-by: Archit Taneja arc...@ti.com
---
  drivers/video/fbdev/omap2/dss/dpi.c |  2 +-
  drivers/video/fbdev/omap2/dss/dss.c | 84 ++---
  drivers/video/fbdev/omap2/dss/dss.h | 27 +++-
  drivers/video/fbdev/omap2/dss/sdi.c |  2 +-
  4 files changed, 97 insertions(+), 18 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 9368972..8593567 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -769,7 +769,7 @@ err_datalines:
return r;
  }

-void __exit dpi_uninit_port(void)
+void __exit dpi_uninit_port(struct device_node *port)
  {
if (!dpi.port_initialized)
return;
diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index 6daeb7e..54a84f4 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -70,6 +70,8 @@ struct dss_features {
u8 fck_div_max;
u8 dss_fck_multiplier;
const char *parent_clk_name;
+   enum omap_display_type *ports;
+   int num_ports;
int (*dpi_select_source)(enum omap_channel channel);
  };

@@ -689,6 +691,22 @@ void dss_debug_dump_clocks(struct seq_file *s)
  }
  #endif

+
+static enum omap_display_type omap2plus_ports[] = {
+#ifdef CONFIG_OMAP2_DSS_DPI
+   OMAP_DISPLAY_TYPE_DPI,
+#endif
+};
+
+static enum omap_display_type omap34xx_ports[] = {
+#ifdef CONFIG_OMAP2_DSS_DPI
+   OMAP_DISPLAY_TYPE_DPI,
+#endif
+#ifdef CONFIG_OMAP2_DSS_DSI
+   OMAP_DISPLAY_TYPE_SDI,
+#endif
+};


If you do this, then if you disable DPI from kernel config, the port
indexes change. The above should reflect the hardware, not which drivers
the user has enabled in the kernel.

Also, you used DSI above, not SDI.


  static const struct dss_features omap24xx_dss_feats __initconst = {
/*
 * fck div max is really 16, but the divider range has gaps. The range
@@ -698,6 +716,8 @@ static const struct dss_features omap24xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   2,
.parent_clk_name=   core_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
  };

  static const struct dss_features omap34xx_dss_feats __initconst = {
@@ -705,6 +725,8 @@ static const struct dss_features omap34xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   2,
.parent_clk_name=   dpll4_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap34xx_ports,
+   .num_ports  =   ARRAY_SIZE(omap34xx_ports),
  };

  static const struct dss_features omap3630_dss_feats __initconst = {
@@ -712,6 +734,8 @@ static const struct dss_features omap3630_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll4_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
  };

  static const struct dss_features omap44xx_dss_feats __initconst = {
@@ -719,6 +743,8 @@ static const struct dss_features omap44xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll_per_x2_ck,
.dpi_select_source  =   dss_dpi_select_source_omap4,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
  };

  static const struct dss_features omap54xx_dss_feats __initconst = {
@@ -726,6 +752,8 @@ static const struct dss_features omap54xx_dss_feats 
__initconst = {
.dss_fck_multiplier

[RFC v2 5/5] OMAPDSS: DSS: add reg-id param to dpi_select_source

2014-05-26 Thread Archit Taneja
Add an argument which describes which DPI instance we are referring to when
selecting it's overlay manager.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c |  2 +-
 drivers/video/fbdev/omap2/dss/dss.c | 12 ++--
 drivers/video/fbdev/omap2/dss/dss.h |  2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 962c722..bcf8ee2 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -405,7 +405,7 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
if (r)
goto err_get_dispc;
 
-   r = dss_dpi_select_source(out-manager-id);
+   r = dss_dpi_select_source(out-port_num, out-manager-id);
if (r)
goto err_src_sel;
 
diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index 54a84f4..862e771 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -72,7 +72,7 @@ struct dss_features {
const char *parent_clk_name;
enum omap_display_type *ports;
int num_ports;
-   int (*dpi_select_source)(enum omap_channel channel);
+   int (*dpi_select_source)(int id, enum omap_channel channel);
 };
 
 static struct {
@@ -566,7 +566,7 @@ enum dss_hdmi_venc_clk_source_select 
dss_get_hdmi_venc_clk_source(void)
return REG_GET(DSS_CONTROL, 15, 15);
 }
 
-static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
+static int dss_dpi_select_source_omap2_omap3(int id, enum omap_channel channel)
 {
if (channel != OMAP_DSS_CHANNEL_LCD)
return -EINVAL;
@@ -574,7 +574,7 @@ static int dss_dpi_select_source_omap2_omap3(enum 
omap_channel channel)
return 0;
 }
 
-static int dss_dpi_select_source_omap4(enum omap_channel channel)
+static int dss_dpi_select_source_omap4(int id, enum omap_channel channel)
 {
int val;
 
@@ -594,7 +594,7 @@ static int dss_dpi_select_source_omap4(enum omap_channel 
channel)
return 0;
 }
 
-static int dss_dpi_select_source_omap5(enum omap_channel channel)
+static int dss_dpi_select_source_omap5(int id, enum omap_channel channel)
 {
int val;
 
@@ -620,9 +620,9 @@ static int dss_dpi_select_source_omap5(enum omap_channel 
channel)
return 0;
 }
 
-int dss_dpi_select_source(enum omap_channel channel)
+int dss_dpi_select_source(int id, enum omap_channel channel)
 {
-   return dss.feat-dpi_select_source(channel);
+   return dss.feat-dpi_select_source(id, channel);
 }
 
 static int dss_get_clocks(void)
diff --git a/drivers/video/fbdev/omap2/dss/dss.h 
b/drivers/video/fbdev/omap2/dss/dss.h
index c91f5bd..cf0a151 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -209,7 +209,7 @@ int dss_init_platform_driver(void) __init;
 void dss_uninit_platform_driver(void);
 
 unsigned long dss_get_dispc_clk_rate(void);
-int dss_dpi_select_source(enum omap_channel channel);
+int dss_dpi_select_source(int id, enum omap_channel channel);
 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 3/5] OMAPDSS: DPI: support multiple DPI instances

2014-05-26 Thread Archit Taneja
SoCs containing DSS until now had only one DPI instance. DRA7x has 3 DPI
instances.

In order to support multiple instances, we allocate a driver data
struct(dpi_data) for each instance. This is somewhat similar to how DSI driver
was changed to support multiple instances.

One difference is that there aren't platform devices for each DPI instance
when DT is used. In the DT case, we store the dpi_data pointer in the DPI port's
(of the type struct device_node) data pointer. In the non DT case, we still
have dummy platform devices, and the device's private data pointer is used to
store the DPI instance's dpi_data.

dpi_init_output/dpi_uninit_output are untouched and only used for non DT case,
dpi_init_output_port/dpi_uninit_output_port are used in the DT case, where DSS
configures the ports using dpi_init_port/dpi_uninit_port.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c | 263 +---
 1 file changed, 181 insertions(+), 82 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 8593567..43966a7 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -37,7 +37,7 @@
 #include dss.h
 #include dss_features.h
 
-static struct {
+struct dpi_data {
struct platform_device *pdev;
 
struct regulator *vdds_dsi_reg;
@@ -52,7 +52,27 @@ static struct {
struct omap_dss_device output;
 
bool port_initialized;
-} dpi;
+};
+
+static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device 
*dssdev)
+{
+   struct device_node *parent = dssdev-dev-of_node;
+
+   /* non DT */
+   if (!parent) {
+   struct omap_dss_device *out = dssdev-src;
+
+   return dev_get_drvdata(out-dev);
+   }
+
+   return container_of(dssdev, struct dpi_data, output);
+}
+
+/* use only for non DT mode */
+static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
+{
+   return dev_get_drvdata(pdev-dev);
+}
 
 static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
 {
@@ -200,15 +220,16 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
dpi_calc_dispc_cb, ctx);
 }
 
-static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
+static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
+   struct dpi_clk_calc_ctx *ctx)
 {
unsigned long clkin;
unsigned long pll_min, pll_max;
 
-   clkin = dsi_get_pll_clkin(dpi.dsidev);
+   clkin = dsi_get_pll_clkin(dpi-dsidev);
 
memset(ctx, 0, sizeof(*ctx));
-   ctx-dsidev = dpi.dsidev;
+   ctx-dsidev = dpi-dsidev;
ctx-pck_min = pck - 1000;
ctx-pck_max = pck + 1000;
ctx-dsi_cinfo.clkin = clkin;
@@ -216,7 +237,7 @@ static bool dpi_dsi_clk_calc(unsigned long pck, struct 
dpi_clk_calc_ctx *ctx)
pll_min = 0;
pll_max = 0;
 
-   return dsi_pll_calc(dpi.dsidev, clkin,
+   return dsi_pll_calc(dpi-dsidev, clkin,
pll_min, pll_max,
dpi_calc_pll_cb, ctx);
 }
@@ -252,7 +273,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct 
dpi_clk_calc_ctx *ctx)
 
 
 
-static int dpi_set_dsi_clk(enum omap_channel channel,
+static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
 {
@@ -260,18 +281,18 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
int r;
bool ok;
 
-   ok = dpi_dsi_clk_calc(pck_req, ctx);
+   ok = dpi_dsi_clk_calc(dpi, pck_req, ctx);
if (!ok)
return -EINVAL;
 
-   r = dsi_pll_set_clock_div(dpi.dsidev, ctx.dsi_cinfo);
+   r = dsi_pll_set_clock_div(dpi-dsidev, ctx.dsi_cinfo);
if (r)
return r;
 
dss_select_lcd_clk_source(channel,
dpi_get_alt_clk_src(channel));
 
-   dpi.mgr_config.clock_info = ctx.dispc_cinfo;
+   dpi-mgr_config.clock_info = ctx.dispc_cinfo;
 
*fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
*lck_div = ctx.dispc_cinfo.lck_div;
@@ -280,8 +301,8 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
return 0;
 }
 
-static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
-   int *lck_div, int *pck_div)
+static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
+   unsigned long *fck, int *lck_div, int *pck_div)
 {
struct dpi_clk_calc_ctx ctx;
int r;
@@ -295,7 +316,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, 
unsigned long *fck,
if (r)
return r;
 
-   dpi.mgr_config.clock_info = ctx.dispc_cinfo;
+   dpi-mgr_config.clock_info = ctx.dispc_cinfo;
 
*fck = ctx.fck;
*lck_div = ctx.dispc_cinfo.lck_div;
@@ -304,19 +325,21 @@ static int

[RFC v2 1/5] OMAPDSS: DSS: init dss ports cleanly

2014-05-26 Thread Archit Taneja
The init/uninit port functions are used to set up the DPI and SDI outputs under
the dss platform device. A 'reg' property is used to determine whether the node
is DPI or SDI for OMAP34xx DSS revision. For other DSS revisions, only DPI
output exists.

For multiple DPI output instances(introduced in DRA7xx DSS), we would use the
'reg' property in dts to specify the DPI output instance.

The current functions work fine if there is only one DPI output instance in
DSS. For multiple DPI instances, it would get complicated to figure out whether
'reg' is used to specify whether the output is SDI, or another DPI instance.

We create a list of port types supported for each DSS rev, with the index of the
port in the list matching the reg id. This allows us to have a more generic way
to init/uninit ports within DSS, and support multiple DPI ports.

Also, make the uninit_port functions iterative since we will have multiple DPI
ports to uninit in the future.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c |  2 +-
 drivers/video/fbdev/omap2/dss/dss.c | 84 ++---
 drivers/video/fbdev/omap2/dss/dss.h | 27 +++-
 drivers/video/fbdev/omap2/dss/sdi.c |  2 +-
 4 files changed, 97 insertions(+), 18 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 9368972..8593567 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -769,7 +769,7 @@ err_datalines:
return r;
 }
 
-void __exit dpi_uninit_port(void)
+void __exit dpi_uninit_port(struct device_node *port)
 {
if (!dpi.port_initialized)
return;
diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index 6daeb7e..54a84f4 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -70,6 +70,8 @@ struct dss_features {
u8 fck_div_max;
u8 dss_fck_multiplier;
const char *parent_clk_name;
+   enum omap_display_type *ports;
+   int num_ports;
int (*dpi_select_source)(enum omap_channel channel);
 };
 
@@ -689,6 +691,22 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+
+static enum omap_display_type omap2plus_ports[] = {
+#ifdef CONFIG_OMAP2_DSS_DPI
+   OMAP_DISPLAY_TYPE_DPI,
+#endif
+};
+
+static enum omap_display_type omap34xx_ports[] = {
+#ifdef CONFIG_OMAP2_DSS_DPI
+   OMAP_DISPLAY_TYPE_DPI,
+#endif
+#ifdef CONFIG_OMAP2_DSS_DSI
+   OMAP_DISPLAY_TYPE_SDI,
+#endif
+};
+
 static const struct dss_features omap24xx_dss_feats __initconst = {
/*
 * fck div max is really 16, but the divider range has gaps. The range
@@ -698,6 +716,8 @@ static const struct dss_features omap24xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   2,
.parent_clk_name=   core_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static const struct dss_features omap34xx_dss_feats __initconst = {
@@ -705,6 +725,8 @@ static const struct dss_features omap34xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   2,
.parent_clk_name=   dpll4_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap34xx_ports,
+   .num_ports  =   ARRAY_SIZE(omap34xx_ports),
 };
 
 static const struct dss_features omap3630_dss_feats __initconst = {
@@ -712,6 +734,8 @@ static const struct dss_features omap3630_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll4_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static const struct dss_features omap44xx_dss_feats __initconst = {
@@ -719,6 +743,8 @@ static const struct dss_features omap44xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll_per_x2_ck,
.dpi_select_source  =   dss_dpi_select_source_omap4,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static const struct dss_features omap54xx_dss_feats __initconst = {
@@ -726,6 +752,8 @@ static const struct dss_features omap54xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll_per_x2_ck,
.dpi_select_source  =   dss_dpi_select_source_omap5,
+   .ports  =   omap2plus_ports,
+   .num_ports  =   ARRAY_SIZE(omap2plus_ports),
 };
 
 static const struct dss_features am43xx_dss_feats

[RFC v2 2/5] OMAPDSS: DT: Get source endpoint by matching reg-id

2014-05-26 Thread Archit Taneja
In omapdss_of_find_source_for_first_ep, we retrieve a source endpoint's DT node,
and then see what omapdss output has the matching device_node pointer in
omap_dss_find_output_by_node.

For all DPI and SDI outputs, the device_node pointer is set as the parent's DSS
device_node pointer. If the source is one of these outputs, the above method
won't work.

To get the correct output for ports within DSS(and in other cases in the future,
where multiple ports might be under one device), we require additional
information which is exclusive to the output port.

We create a new field in omap_dss_device called 'port_num', this provides port
number of the output port corresponding to this device. When searching for the
source endpoint in DT, we extract the 'reg' property from the port corresponding
to the endpoint source. From the list of registered outputs, we pick out that
output which has both dev-of_node and port_num matching with the device_node
pointer and 'reg' of the source endpoint node from DT.

For encoder blocks(the ones which have both an input and output port), we need
to set the port_num as the 'reg' property for the output port as defined in the
DT bindings. We set port_num to 1 in the tfp410 and tpd12s015 encoder drivers.

Signed-off-by: Archit Taneja arc...@ti.com
---
 .../fbdev/omap2/displays-new/encoder-tfp410.c  |  1 +
 .../fbdev/omap2/displays-new/encoder-tpd12s015.c   |  1 +
 drivers/video/fbdev/omap2/dss/dss-of.c | 51 +-
 drivers/video/fbdev/omap2/dss/output.c |  8 ++--
 include/video/omapdss.h|  7 ++-
 5 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c 
b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index b4e9a42..d927455 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
@@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev)
dssdev-output_type = OMAP_DISPLAY_TYPE_DVI;
dssdev-owner = THIS_MODULE;
dssdev-phy.dpi.data_lines = ddata-data_lines;
+   dssdev-port_num = 1;
 
r = omapdss_register_output(dssdev);
if (r) {
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c 
b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index 7e33686..9e25fe7 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -389,6 +389,7 @@ static int tpd_probe(struct platform_device *pdev)
dssdev-type = OMAP_DISPLAY_TYPE_HDMI;
dssdev-output_type = OMAP_DISPLAY_TYPE_HDMI;
dssdev-owner = THIS_MODULE;
+   dssdev-port_num = 1;
 
in = ddata-in;
 
diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c 
b/drivers/video/fbdev/omap2/dss/dss-of.c
index a4b20aa..8ba43faa 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -132,28 +132,55 @@ EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node)
 {
-   struct device_node *ep;
-   struct device_node *src_node;
+   struct device_node *ep, *port_ep;
+   struct device_node *src_node, *src_port;
struct omap_dss_device *src;
+   int r;
+   u32 reg;
 
ep = omapdss_of_get_first_endpoint(node);
-   if (!ep)
-   return ERR_PTR(-EINVAL);
+   if (!ep) {
+   r = -EINVAL;
+   goto err_first_ep;
+   }
 
src_node = omapdss_of_get_remote_device_node(ep);
+   if (!src_node) {
+   r = -EINVAL;
+   goto err_src_node;
+   }
 
-   of_node_put(ep);
-
-   if (!src_node)
-   return ERR_PTR(-EINVAL);
+   port_ep = of_parse_phandle(ep, remote-endpoint, 0);
+   if (!port_ep) {
+   r = -EINVAL;
+   goto err_port_ep;
+   }
 
-   src = omap_dss_find_output_by_node(src_node);
+   src_port = of_get_next_parent(port_ep);
+   if (!src_port) {
+   r = -EINVAL;
+   goto err_src_port;
+   }
 
-   of_node_put(src_node);
+   r = of_property_read_u32(src_port, reg, reg);
+   if (r) {
+   r = 0;
+   reg = 0;
+   }
 
+   src = omap_dss_find_output_by_node_and_reg(src_node, reg);
if (!src)
-   return ERR_PTR(-EPROBE_DEFER);
+   r = -EPROBE_DEFER;
+
+   of_node_put(src_port);
 
-   return src;
+err_src_port:
+   of_node_put(port_ep);
+err_port_ep:
+   of_node_put(src_node);
+err_src_node:
+   of_node_put(ep);
+err_first_ep:
+   return r ? ERR_PTR(r) : src;
 }
 EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);
diff --git a/drivers/video/fbdev/omap2/dss/output.c 
b/drivers/video/fbdev/omap2/dss/output.c
index 2ab3afa..1a8d6c7 100644

[RFC v2 4/5] OMAPDSS: DPI: make dpi_get_channel take DPI reg-id

2014-05-26 Thread Archit Taneja
To support multiple DPI instances, dpi_get_channel needs to take the DPI
instance's reg-id to get the corresponding channel. Make it take this
argument.

We just pass 0 in the non-DT path, since we don't support multiple instances
in the non-DT case.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 43966a7..962c722 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -625,7 +625,7 @@ static void dpi_init_pll(struct dpi_data *dpi)
  * the channel in some more dynamic manner, or get the channel as a user
  * parameter.
  */
-static enum omap_channel dpi_get_channel(void)
+static enum omap_channel dpi_get_channel(int reg)
 {
switch (omapdss_get_version()) {
case OMAPDSS_VER_OMAP24xx:
@@ -719,7 +719,7 @@ static void dpi_init_output(struct platform_device *pdev)
out-id = OMAP_DSS_OUTPUT_DPI;
out-output_type = OMAP_DISPLAY_TYPE_DPI;
out-name = dpi.0;
-   out-dispc_channel = dpi_get_channel();
+   out-dispc_channel = dpi_get_channel(0);
out-ops.dpi = dpi_ops;
out-owner = THIS_MODULE;
 
@@ -754,7 +754,7 @@ static void dpi_init_output_port(struct platform_device 
*pdev,
out-dev = pdev-dev;
out-id = OMAP_DSS_OUTPUT_DPI;
out-output_type = OMAP_DISPLAY_TYPE_DPI;
-   out-dispc_channel = dpi_get_channel();
+   out-dispc_channel = dpi_get_channel(reg);
out-ops.dpi = dpi_ops;
out-port_num = reg;
out-owner = THIS_MODULE;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 2/2] ARM: OMAP5: hwmod data: Make DSS hwmods share MODULEMODE fields

2014-05-26 Thread Archit Taneja
This is an example which shows how to use new 'shared modulemode' flag.

DSS hwmods share the MODULEMODE field. Add the new HWMOD_OMAP4_MODULEMODE_SHARED
flag, and create a modulemode_shared struct which the DSS hwmods refer to.

This will allow the hwmods to reset properly during boot, and not break things
when the DSS driver runs.

(Note: hdmi and rfbi hwmods still don't reset properly as they don't have their
mainclks as dss_dss_clk, this will be fixed later).

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 46 +-
 1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index e8bdd7a..762d61f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -337,6 +337,9 @@ static struct omap_hwmod omap54xx_dmic_hwmod = {
  * 'dss' class
  * display sub-system
  */
+
+static struct modulemode_shared dss_modulemode_ref;
+
 static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = {
.rev_offs   = 0x,
.syss_offs  = 0x0014,
@@ -364,9 +367,11 @@ static struct omap_hwmod omap54xx_dss_hwmod = {
.main_clk   = dss_dss_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET,
-   .modulemode   = MODULEMODE_SWCTRL,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .context_offs   = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET,
+   .modulemode = MODULEMODE_SWCTRL,
+   .flags  = HWMOD_OMAP4_MODULEMODE_SHARED,
+   .modulemode_ref = dss_modulemode_ref,
},
},
.opt_clks   = dss_opt_clks,
@@ -414,8 +419,11 @@ static struct omap_hwmod omap54xx_dss_dispc_hwmod = {
.main_clk   = dss_dss_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT |
+ HWMOD_OMAP4_MODULEMODE_SHARED,
+   .modulemode = MODULEMODE_SWCTRL,
+   .modulemode_ref = dss_modulemode_ref,
},
},
.opt_clks   = dss_dispc_opt_clks,
@@ -456,8 +464,11 @@ static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = {
.main_clk   = dss_dss_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT |
+ HWMOD_OMAP4_MODULEMODE_SHARED,
+   .modulemode = MODULEMODE_SWCTRL,
+   .modulemode_ref = dss_modulemode_ref,
},
},
.opt_clks   = dss_dsi1_a_opt_clks,
@@ -476,8 +487,11 @@ static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = {
.main_clk   = dss_dss_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT |
+ HWMOD_OMAP4_MODULEMODE_SHARED,
+   .modulemode = MODULEMODE_SWCTRL,
+   .modulemode_ref = dss_modulemode_ref,
},
},
.opt_clks   = dss_dsi1_c_opt_clks,
@@ -515,8 +529,11 @@ static struct omap_hwmod omap54xx_dss_hdmi_hwmod = {
.main_clk   = dss_48mhz_clk,
.prcm = {
.omap4 = {
-   .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
-   .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+   .clkctrl_offs   = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+   .flags  = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT |
+ HWMOD_OMAP4_MODULEMODE_SHARED,
+   .modulemode = MODULEMODE_SWCTRL,
+   .modulemode_ref = dss_modulemode_ref,
},
},
.opt_clks   = dss_hdmi_opt_clks,
@@ -554,8 +571,11 @@ static struct omap_hwmod omap54xx_dss_rfbi_hwmod = {
.clkdm_name = dss_clkdm

[RFC 1/2] ARM: OMAP2+: hwmod: Add refcounting for modulemode shared by multiple hwmods

2014-05-26 Thread Archit Taneja
Generally, IP blocks/modules within a clock domain each have their own
CM_x_CLKCTRL register, each having it's own MODULEMODE field to manage the
module.

DSS clockdoain, however, has multiple modules in it, but only one register
named CM_DSS_DSS_CLKCTRL, which contains one MODULEMODE register field.

Until now, we defined '.prcm.omap4.modulemode' only for the top level DSS
hwmod(dss_core) and didn't define it for other DSS hwmods(like dss_dispc,
dss_dsi1 and so on). This made the omapdss driver work as the top level DSS
platform device and the rest had a parent-child relationship. This ensured that
the parent hwmod(dss_core) is enabled if any of the children hwmods are
enabled while using omapdss.

This method, however, doesn't work when each hwmod is enabled individually.
This happens early in boot in omap_hwmod_setup_all, where each hwmod is enabled,
and then reset and idled. All the 'children' DSS hwmods fail to enable and
reset, since they don't enable modulemode.

The way to make such modules work both during initialization and when used by
pm runtime API in the driver would be to add refcounting for enabling/disabling
the modulemode field.

We add a new flag bit for the flag in omap_hwmod_omap4_prcm, which tells
omap_hwmod that this hwmod uses a modulemode field shared by other hwmods.

We create a struct called 'modulemode_shared'. The hwmod data file should define
a static instance of this struct. Each hwmod that uses this modulemode field
should hold a pointer to this instance.

omap_hwmod's soc enable_module and disable_module ops set the MODULEMODE
reigster bits only when the first module using it is enabled, or the last module
using it is disabled. We serialize accesses to the struct with a spinlock.

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod.c | 123 +--
 arch/arm/mach-omap2/omap_hwmod.h |  38 +---
 2 files changed, 133 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 66c60fe..b42718d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -973,17 +973,33 @@ static void _disable_optional_clocks(struct omap_hwmod 
*oh)
  */
 static void _omap4_enable_module(struct omap_hwmod *oh)
 {
+   unsigned long flags;
+   struct modulemode_shared *mmode = NULL;
+   bool enable = true;
+
if (!oh-clkdm || !oh-prcm.omap4.modulemode)
return;
 
pr_debug(omap_hwmod: %s: %s: %d\n,
 oh-name, __func__, oh-prcm.omap4.modulemode);
 
-   omap4_cminst_module_enable(oh-prcm.omap4.modulemode,
-  oh-clkdm-prcm_partition,
-  oh-clkdm-cm_inst,
-  oh-clkdm-clkdm_offs,
-  oh-prcm.omap4.clkctrl_offs);
+   if (oh-prcm.omap4.flags  HWMOD_OMAP4_MODULEMODE_SHARED) {
+   mmode = oh-prcm.omap4.modulemode_ref;
+
+   spin_lock_irqsave(mmode-lock, flags);
+
+   enable = mmode-refcnt++ == 0;
+   }
+
+   if (enable)
+   omap4_cminst_module_enable(oh-prcm.omap4.modulemode,
+  oh-clkdm-prcm_partition,
+  oh-clkdm-cm_inst,
+  oh-clkdm-clkdm_offs,
+  oh-prcm.omap4.clkctrl_offs);
+
+   if (mmode)
+   spin_unlock_irqrestore(mmode-lock, flags);
 }
 
 /**
@@ -995,15 +1011,32 @@ static void _omap4_enable_module(struct omap_hwmod *oh)
  */
 static void _am33xx_enable_module(struct omap_hwmod *oh)
 {
+   unsigned long flags;
+   struct modulemode_shared *mmode = NULL;
+   bool enable = true;
+
if (!oh-clkdm || !oh-prcm.omap4.modulemode)
return;
 
pr_debug(omap_hwmod: %s: %s: %d\n,
 oh-name, __func__, oh-prcm.omap4.modulemode);
 
-   am33xx_cm_module_enable(oh-prcm.omap4.modulemode, oh-clkdm-cm_inst,
-   oh-clkdm-clkdm_offs,
-   oh-prcm.omap4.clkctrl_offs);
+   if (oh-prcm.omap4.flags  HWMOD_OMAP4_MODULEMODE_SHARED) {
+   mmode = oh-prcm.omap4.modulemode_ref;
+
+   spin_lock_irqsave(mmode-lock, flags);
+
+   enable = mmode-refcnt++ == 0;
+   }
+
+   if (enable)
+   am33xx_cm_module_enable(oh-prcm.omap4.modulemode,
+   oh-clkdm-cm_inst,
+   oh-clkdm-clkdm_offs,
+   oh-prcm.omap4.clkctrl_offs);
+
+   if (mmode)
+   spin_unlock_irqrestore(mmode-lock, flags);
 }
 
 /**
@@ -1846,6 +1879,9 @@ static bool _are_any_hardreset_lines_asserted(struct 
omap_hwmod *oh)
 static int _omap4_disable_module(struct omap_hwmod *oh)
 {
int v;
+   unsigned long

Re: [RFC 2/6] omapdss: add init port functions for different omap revs

2014-05-20 Thread Archit Taneja

On Tuesday 20 May 2014 01:34 PM, Tomi Valkeinen wrote:

On 08/05/14 12:15, Archit Taneja wrote:

The init/uninit port functions are used to set up the DPI and SDI outputs under
the dss platform device. A 'reg' property is used to determine whether the node
is DPI or SDI for OMAP34xx DSS revision. For other DSS revisions, only DPI
output exists.

For multiple DPI output instances(introduced in DRA7xx DSS), we would use the
'reg' property to specify the DPI output number.

The current functions work fine if there is only one DPI output instance in
DSS. For multiple DPI instances, it would get complicated to figure out whether
'reg' is used to specify whether the output is SDI, or a later DPI instance.

Create DSS revision specific init/uninit_port functions such that we have a
separate functions for OMAP34xx, this helps us deal with the SDI case
separately.


Could we instead have an array of the ports for the said DSS version,
assigned to dss_features? Maybe just something like:

static enum omap_display_type omap34xx_ports[] = {
OMAP_DISPLAY_TYPE_DPI,
OMAP_DISPLAY_TYPE_SDI,
};

The index on the array tells the matching 'reg' value.


Oh yeah! That should prevent us creating ops. It would require us to 
create a ports pointer in dss_features, but it's certainly much better 
than having 2 very similar functions.


Archit
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 00/11] ARM: OMAP: OMAP5 AM43x DSS

2014-05-19 Thread Archit Taneja

Hi,

On Friday 16 May 2014 01:44 PM, Tomi Valkeinen wrote:

On 12/05/14 18:48, Tony Lindgren wrote:


Also, I'm wondering why we still have .clk and .opt_clks entries in the
hwmod data for am43xx and omap5 which are both device tree based with
all the clocks coming from .dts files?


I think they are needed for the omap_device/hwmod stuff to work. Only
omapdss driver knows about the clocks defined in the .dts files, and the
omap_device/hwmod code still needs to do the reset and maybe some other
tasks that require the clocks.


We're already populating the hwmod data from dts entries, that's done by
omap_device_build_from_dt. Why aren't we doing that for dt defined clocks?

I'd rather not start adding new data that will then just be removed, that's
what people call pointless extra churn.


I don't know why. I have to say I'm not 100% sure if that's done or not,
but at least I can't find where it's done.


The reason why clocks are needed from hwmod data is because we still 
don't populate hwmod fields like main_clk and opt_clock from DT clocks.


The reason why this isn't done yet is because we currently haven't 
figured out a clean way to tell hwmod what clock is the main_clk, and 
what clocks are optional clocks.


One of the proposed methods was to assume the clock named to be fck as 
main_clk, and the remaining clocks as optional clocks for hwmod. That 
method wasn't agreed upon, this looks like the thread which discusses this:


http://marc.info/?l=linux-arm-kernelm=138928084823142w=2

Archit


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/5] Doc/DT: hdmi-connector: add HPD GPIO documentation

2014-05-11 Thread Archit Taneja

Hi,

On Friday 09 May 2014 06:02 PM, Tomi Valkeinen wrote:

Add binding documentation for HDMI connector's HPD GPIO.

Signed-off-by: Tomi Valkeinen tomi.valkei...@ti.com
Cc: devicet...@vger.kernel.org
---
  Documentation/devicetree/bindings/video/hdmi-connector.txt | 1 +
  1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/video/hdmi-connector.txt 
b/Documentation/devicetree/bindings/video/hdmi-connector.txt
index c19e2573..acd5668b1ce1 100644
--- a/Documentation/devicetree/bindings/video/hdmi-connector.txt
+++ b/Documentation/devicetree/bindings/video/hdmi-connector.txt
@@ -7,6 +7,7 @@ Required properties:

  Optional properties:
  - label: a symbolic name for the connector
+- hpd-gpios: HPD GPIO number


Would there ever be more than one HPD gpio?

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ARM: OMAP5: DSS hwmod data

2014-05-09 Thread Archit Taneja

Hi Paul,

On Thursday 08 May 2014 09:31 PM, Paul Walmsley wrote:
snip


The problem is that we have multiple hwmods which use the same MODULEMODE bit.
There is no use-counting done when it comes to enabling/disabling modulemode.
If there was such a thing, we could have provided MODULEMODE flags even for
the children hwmods.


Thanks for the summary.  This is indeed a long-overdue item for the hwmod
core code.  Can you please patch the hwmod core code to add this?  I'd
suggest making the use-counting functionality conditional on a hwmod flag
that you can set for all of the DSS hwmods.  (Ideally, the core code would
detect that several modules share the same MODULEMODE bits, and
automatically set it for those cases, but that seems a bit too complex for
a first cut.)


Sure, I can work on this.

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 2/4] ARM: dts: Add ctrl-core DT node for DRA7

2014-05-08 Thread Archit Taneja

On Tuesday 06 May 2014 07:56 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140505 22:24]:

Hi,

On Monday 21 April 2014 08:40 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140420 22:16]:

Hi,

On Friday 18 April 2014 10:48 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140416 06:20]:

Add DT node for the ctrl-core sub module of the DRA7 control module. We map the
CTRL_MODULE_CORE address region up to 0x4a002d60, this region contains register
fields which configure clocks. The remainder of the registers are related to
pad configurations or cross-bar configurations, and therefore aren't mapped.


Can you please check if this can just use the existing
regmap syscon mapping:

syscon = dra7_ctrl_general;

See how the drivers/regulator/pbias-regulator.c is using the
syscon to initialize a regulator and then omap_hsmmc.c just does
the standard regulator calls.


The thing is that this bit needs to be set before the the DSS hwmods are
reset, and that happens very early. If we don't do this, DSS won't reset
properly, and not get back to an idle state.

I am not sure where I can configure the syscon register early enough that it
happens before the hwmods are reset. With a syscon mapping, I guess we would
access the register when the DSS driver is probed. But that's too late for
us.

Ideally, it would be much better to have a syscon mapping. Do you have any
suggestions how this can be achieved very early in boot?


It's best to move the reset and initialization of DSS happen later. I believe
we already are resetting only some of the hwmods early on.



I looked at this in some more detail. With the current hwmod
flags(HWMOD_INIT_NO_RESET/NO_IDLE), we still try to enable the IP, it's just
the reset part(ocp reset/custom reset and sysc register) or the disable part
that is skipped. hwmod still tries to enable the IP.

This again results in the same issue.

One thing which wasn't clear was that why do we enable a hwmod in the first
place, if we know that we are going to skip reset?


Probably to configure the idle bits. In general, we should configure the
modules lazily as the driver probes as requested, and then idle the
unused modules with a late_initcall.


Okay, we were thinking of changing the hwmod code to skip enable for 
hwmods(which have the HWMOD_INIT_NO_RESET flag) altogether. But that 
doesn't seem like a viable option.


I can't think of any other way of getting around this, besides making 
control module a clock provider.


Paul said that it's not that bad to make DRA7 CTRL module a clock 
provider, but outside of PRCM code. I guess that would involve having 
something along the lines of of_prcm_init() in mach-omap2/control.c


Archit


Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V5 0/3] arm: dts: dra7: Updates for adding crossbar device

2014-05-08 Thread Archit Taneja

On Wednesday 07 May 2014 03:15 AM, Darren Etheridge wrote:

Sricharan R r.sricha...@ti.com wrote on Tue [2014-May-06 19:26:16 +0530]:

Some socs have a large number of interrupts requests to service
the needs of its many peripherals and subsystems. All of the interrupt
requests lines from the subsystems are not needed at the same
time, so they have to be muxed to the controllers appropriately.
In such places a interrupt controllers are preceded by an
IRQ CROSSBAR that provides flexibility in muxing the device interrupt
requests to the controller inputs.

The dts file update to support the crossbar device and convert
peripheral irq numbers to crossbar number are added here.

This is a rebase of V4 series on top of 3.15-rc4

This series depends on crossbar-driver-fixes sent below
http://marc.info/?l=linux-omapm=139929963420299w=2

Sricharan R (3):
   arm: dts: dra7: Add crossbar device binding
   arm: dts: dra7: Replace peripheral interrupt numbers with crossbar
 inputs
   arm: dts: dra7: Add routable-irqs property for gic node



OK, assuming the bisectability issues discussed earlier on this thread
are addressed.  I have tested the earlier crossbar patch series in
conjunction with this dts series with VIP capture and DSS display
running together on DRA7.  Looks good with this combination of
devices. VIP is one of the modules that must have a crossbar mapping as
there is no default interrupt mapping for it, therefore VIP makes a good
test case.

So please feel free to add:

Tested-by: Darren Etheridge detheri...@ti.com


DMM doesn't get used by default since it's hwmod is missing in DRA7x's 
hwmod data. I added the hwmod and tried using dmm with omapdrm, it works 
fine.


So, for DSS and DMM:

Tested-by: Archit Taneja arc...@ti.com





  arch/arm/boot/dts/dra7.dtsi |  109 +--
  1 file changed, 63 insertions(+), 46 deletions(-)

--
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 2/4] ARM: dts: Add ctrl-core DT node for DRA7

2014-05-08 Thread Archit Taneja

On Thursday 08 May 2014 01:23 PM, Tero Kristo wrote:

On 05/08/2014 09:02 AM, Archit Taneja wrote:

On Tuesday 06 May 2014 07:56 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140505 22:24]:

Hi,

On Monday 21 April 2014 08:40 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140420 22:16]:

Hi,

On Friday 18 April 2014 10:48 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140416 06:20]:

Add DT node for the ctrl-core sub module of the DRA7 control
module. We map the
CTRL_MODULE_CORE address region up to 0x4a002d60, this region
contains register
fields which configure clocks. The remainder of the registers are
related to
pad configurations or cross-bar configurations, and therefore
aren't mapped.


Can you please check if this can just use the existing
regmap syscon mapping:

syscon = dra7_ctrl_general;

See how the drivers/regulator/pbias-regulator.c is using the
syscon to initialize a regulator and then omap_hsmmc.c just does
the standard regulator calls.


The thing is that this bit needs to be set before the the DSS
hwmods are
reset, and that happens very early. If we don't do this, DSS won't
reset
properly, and not get back to an idle state.

I am not sure where I can configure the syscon register early
enough that it
happens before the hwmods are reset. With a syscon mapping, I guess
we would
access the register when the DSS driver is probed. But that's too
late for
us.

Ideally, it would be much better to have a syscon mapping. Do you
have any
suggestions how this can be achieved very early in boot?


It's best to move the reset and initialization of DSS happen later.
I believe
we already are resetting only some of the hwmods early on.



I looked at this in some more detail. With the current hwmod
flags(HWMOD_INIT_NO_RESET/NO_IDLE), we still try to enable the IP,
it's just
the reset part(ocp reset/custom reset and sysc register) or the
disable part
that is skipped. hwmod still tries to enable the IP.

This again results in the same issue.

One thing which wasn't clear was that why do we enable a hwmod in the
first
place, if we know that we are going to skip reset?


Probably to configure the idle bits. In general, we should configure the
modules lazily as the driver probes as requested, and then idle the
unused modules with a late_initcall.


Okay, we were thinking of changing the hwmod code to skip enable for
hwmods(which have the HWMOD_INIT_NO_RESET flag) altogether. But that
doesn't seem like a viable option.

I can't think of any other way of getting around this, besides making
control module a clock provider.

Paul said that it's not that bad to make DRA7 CTRL module a clock
provider, but outside of PRCM code. I guess that would involve having
something along the lines of of_prcm_init() in mach-omap2/control.c


That sounds like pretty much one of the things I have done here:

https://github.com/t-kristo/linux-pm/tree/3.14-rc4-cm-prm-driver-wip

The patches in their current form haven't been posted yet though, as
they are waiting for some of the pre-reqs, but feel free to re-use
something from here.


Ah nice, thanks!

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 1/6] omapdss: remove check for simpler port/endpoint binding

2014-05-08 Thread Archit Taneja
The support for simpler port/endpoint binding was removed in the merged version
of omapdss DT. But dss_init_ports still tries to get to an endpoint even if no
port exists. Remove this as this doesn't work.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dss.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index d55266c..31ef262 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -784,12 +784,8 @@ static int __init dss_init_ports(struct platform_device 
*pdev)
return 0;
 
port = omapdss_of_get_next_port(parent, NULL);
-   if (!port) {
-#ifdef CONFIG_OMAP2_DSS_DPI
-   dpi_init_port(pdev, parent);
-#endif
+   if (!port)
return 0;
-   }
 
do {
u32 reg;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 2/6] omapdss: add init port functions for different omap revs

2014-05-08 Thread Archit Taneja
The init/uninit port functions are used to set up the DPI and SDI outputs under
the dss platform device. A 'reg' property is used to determine whether the node
is DPI or SDI for OMAP34xx DSS revision. For other DSS revisions, only DPI
output exists.

For multiple DPI output instances(introduced in DRA7xx DSS), we would use the
'reg' property to specify the DPI output number.

The current functions work fine if there is only one DPI output instance in
DSS. For multiple DPI instances, it would get complicated to figure out whether
'reg' is used to specify whether the output is SDI, or a later DPI instance.

Create DSS revision specific init/uninit_port functions such that we have a
separate functions for OMAP34xx, this helps us deal with the SDI case
separately.

Also, make the uninit_port functions iterative since we will have multiple DPI
ports in the future.

dpi_uninit_port/sdi_uninit_port functions have to be removed from the exit
section as dss_features(which is initconst data) uses it, this prevents the
section mismatch.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c |  2 +-
 drivers/video/fbdev/omap2/dss/dss.c | 88 ++---
 drivers/video/fbdev/omap2/dss/dss.h |  4 +-
 drivers/video/fbdev/omap2/dss/sdi.c |  2 +-
 4 files changed, 86 insertions(+), 10 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 157921d..6593c8b 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -765,7 +765,7 @@ err_datalines:
return r;
 }
 
-void __exit dpi_uninit_port(void)
+void dpi_uninit_port(struct platform_device *pdev, struct device_node *port)
 {
if (!dpi.port_initialized)
return;
diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index 31ef262..c415029 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -65,12 +65,18 @@ struct dss_reg {
 
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
+static int __init dss_init_ports(struct platform_device *pdev);
+static int __init dss_init_ports_omap34xx(struct platform_device *pdev);
+static void dss_uninit_ports(struct platform_device *pdev);
+static void dss_uninit_ports_omap34xx(struct platform_device *pdev);
 
 struct dss_features {
u8 fck_div_max;
u8 dss_fck_multiplier;
const char *parent_clk_name;
int (*dpi_select_source)(enum omap_channel channel);
+   int (*init_ports)(struct platform_device *pdev);
+   void (*uninit_ports)(struct platform_device *pdev);
 };
 
 static struct {
@@ -698,6 +704,8 @@ static const struct dss_features omap24xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   2,
.parent_clk_name=   core_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .init_ports =   dss_init_ports,
+   .uninit_ports   =   dss_uninit_ports,
 };
 
 static const struct dss_features omap34xx_dss_feats __initconst = {
@@ -705,6 +713,8 @@ static const struct dss_features omap34xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   2,
.parent_clk_name=   dpll4_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .init_ports =   dss_init_ports_omap34xx,
+   .uninit_ports   =   dss_uninit_ports_omap34xx,
 };
 
 static const struct dss_features omap3630_dss_feats __initconst = {
@@ -712,6 +722,8 @@ static const struct dss_features omap3630_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll4_ck,
.dpi_select_source  =   dss_dpi_select_source_omap2_omap3,
+   .init_ports =   dss_init_ports,
+   .uninit_ports   =   dss_uninit_ports,
 };
 
 static const struct dss_features omap44xx_dss_feats __initconst = {
@@ -719,6 +731,8 @@ static const struct dss_features omap44xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll_per_x2_ck,
.dpi_select_source  =   dss_dpi_select_source_omap4,
+   .init_ports =   dss_init_ports,
+   .uninit_ports   =   dss_uninit_ports,
 };
 
 static const struct dss_features omap54xx_dss_feats __initconst = {
@@ -726,6 +740,8 @@ static const struct dss_features omap54xx_dss_feats 
__initconst = {
.dss_fck_multiplier =   1,
.parent_clk_name=   dpll_per_x2_ck,
.dpi_select_source  =   dss_dpi_select_source_omap5,
+   .init_ports =   dss_init_ports,
+   .uninit_ports   =   dss_uninit_ports,
 };
 
 static int __init dss_init_features(struct platform_device *pdev)
@@ -774,7 +790,7 @@ static int __init dss_init_features

[RFC 3/6] omapdss: DT: Get source endpoint by matching reg-id

2014-05-08 Thread Archit Taneja
In omapdss_of_find_source_for_first_ep, we retrieve a source endpoint's DT node,
and then see what omapdss output has the matching device_node pointer in
omap_dss_find_output_by_node.

For all DPI and SDI outputs, the device_node pointer is set as the parent's DSS
device_node pointer. If the source is one of these outputs, the above method
won't work.

To get the correct output for ports within DSS with the existing omapdss DT
framework, we check in omapdss_of_find_source_for_first_ep, whether the source
node is of the DSS parent device. If so, we take an extra step of extracting
the 'reg' property from the port corresponding to the endpoint source, and get
the omap_dss_device output by matching both device_node and reg-id.

We would want to get rid of this eventually, and support multiple ports in
general. That would involve making some more changes the omapdss DT
framework.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dss-of.c | 41 ++
 drivers/video/fbdev/omap2/dss/dss.c|  6 +
 drivers/video/fbdev/omap2/dss/dss.h|  2 ++
 drivers/video/fbdev/omap2/dss/output.c | 15 +
 include/video/omapdss.h|  6 +
 5 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c 
b/drivers/video/fbdev/omap2/dss/dss-of.c
index a4b20aa..4261c14 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -19,6 +19,7 @@
 #include linux/seq_file.h
 
 #include video/omapdss.h
+#include dss.h
 
 struct device_node *
 omapdss_of_get_next_port(const struct device_node *parent,
@@ -142,12 +143,44 @@ omapdss_of_find_source_for_first_ep(struct device_node 
*node)
 
src_node = omapdss_of_get_remote_device_node(ep);
 
-   of_node_put(ep);
-
-   if (!src_node)
+   if (!src_node) {
+   of_node_put(ep);
return ERR_PTR(-EINVAL);
+   }
 
-   src = omap_dss_find_output_by_node(src_node);
+   /*
+* TODO: Find a better solution for this.
+*
+* DPI and SDI outputs share the same DSS device node. In order to find
+* the correct omap_dss_device output, we need to match the reg-id
+* property of the DPI/SDI port.
+*
+* For the special case of device_node being the parent DSS device, make
+* sure we check for both device_node and reg-id to get the correct
+* source
+*/
+   if (src_node == dss_device_node()) {
+   struct device_node *src_port;
+   u32 reg;
+   int r;
+
+   src_port = of_parse_phandle(ep, remote-endpoint, 0);
+
+   /* the parent of the endpoint is always the port node */
+   src_port = of_get_next_parent(src_port);
+
+   r = of_property_read_u32(src_port, reg, reg);
+   if (r)
+   reg = 0;
+
+   of_node_put(src_port);
+
+   src = omap_dss_find_output_by_node_and_reg(src_node, reg);
+   } else {
+   src = omap_dss_find_output_by_node(src_node);
+   }
+
+   of_node_put(ep);
 
of_node_put(src_node);
 
diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index c415029..4087f3b 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -790,6 +790,12 @@ static int __init dss_init_features(struct platform_device 
*pdev)
return 0;
 }
 
+/* of_node pointer for the DSS parent node */
+struct device_node *dss_device_node(void)
+{
+   return dss.pdev-dev.of_node;
+}
+
 static int __init dss_init_ports_omap34xx(struct platform_device *pdev)
 {
struct device_node *parent = pdev-dev.of_node;
diff --git a/drivers/video/fbdev/omap2/dss/dss.h 
b/drivers/video/fbdev/omap2/dss/dss.h
index 9f4ee49..6f68f72 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -240,6 +240,8 @@ typedef bool (*dss_div_calc_func)(unsigned long fck, void 
*data);
 bool dss_div_calc(unsigned long pck, unsigned long fck_min,
dss_div_calc_func func, void *data);
 
+struct device_node *dss_device_node(void);
+
 /* SDI */
 int sdi_init_platform_driver(void) __init;
 void sdi_uninit_platform_driver(void) __exit;
diff --git a/drivers/video/fbdev/omap2/dss/output.c 
b/drivers/video/fbdev/omap2/dss/output.c
index 2ab3afa..2b556f1 100644
--- a/drivers/video/fbdev/omap2/dss/output.c
+++ b/drivers/video/fbdev/omap2/dss/output.c
@@ -144,6 +144,21 @@ struct omap_dss_device 
*omap_dss_find_output_by_node(struct device_node *node)
 }
 EXPORT_SYMBOL(omap_dss_find_output_by_node);
 
+struct omap_dss_device
+   *omap_dss_find_output_by_node_and_reg(struct device_node *node,
+   u32 reg)
+{
+   struct omap_dss_device *out;
+
+   list_for_each_entry(out, output_list, list) {
+   if (out-dev-of_node == node  out

[RFC 5/6] omapdss: DPI: make dpi_get_channel take DPI reg-id

2014-05-08 Thread Archit Taneja
To support multiple DPI instances, dpi_get_channel needs to take the DPI
instance's reg-id to get the corresponding channel. Make it take this
argument.

We just pass 0 in the non-DT path, since we don't support multiple instances
in the non-DT case.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index b891e17..faf266e 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -640,7 +640,7 @@ static void dpi_init_pll(struct dpi_data *dpi)
  * the channel in some more dynamic manner, or get the channel as a user
  * parameter.
  */
-static enum omap_channel dpi_get_channel(void)
+static enum omap_channel dpi_get_channel(int reg)
 {
switch (omapdss_get_version()) {
case OMAPDSS_VER_OMAP24xx:
@@ -733,7 +733,7 @@ static void dpi_init_output(struct platform_device *pdev)
out-id = OMAP_DSS_OUTPUT_DPI;
out-output_type = OMAP_DISPLAY_TYPE_DPI;
out-name = dpi.0;
-   out-dispc_channel = dpi_get_channel();
+   out-dispc_channel = dpi_get_channel(0);
out-ops.dpi = dpi_ops;
out-owner = THIS_MODULE;
 
@@ -768,7 +768,7 @@ static void dpi_init_output_port(struct platform_device 
*pdev,
out-dev = pdev-dev;
out-id = OMAP_DSS_OUTPUT_DPI;
out-output_type = OMAP_DISPLAY_TYPE_DPI;
-   out-dispc_channel = dpi_get_channel();
+   out-dispc_channel = dpi_get_channel(reg);
out-ops.dpi = dpi_ops;
out-reg = reg;
out-owner = THIS_MODULE;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 4/6] omapdss: DPI: support multiple DPI instances

2014-05-08 Thread Archit Taneja
SoCs containing DSS until now had only one DPI instance. DRA7x has 3 DPI
instances.

In order to support multiple instances, we allocate a driver data
struct(dpi_data) for each instance. This is somewhat similar to how DSI driver
was changed to support multiple instances.

One difference is that there are no platform devices for each instance when DT
is used. In the DT case, we store the dpi_data pointer in the DPI port's
(of the type struct device_node) data pointer. In the non DT case, we still
have dummy platform devices, and the device's private data pointer is used to
store the DPI instance's dpi_data.

When an encoder/panel driver calls a dpi op, we get dpi_data using the function
dpi_get_data_from_dssdev. This function iterates through the ports under DSS
device node, and returns the port which has reg-id matching the reg-id specified
in omap_dss_device.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c | 282 +---
 1 file changed, 200 insertions(+), 82 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index 6593c8b..b891e17 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -37,7 +37,7 @@
 #include dss.h
 #include dss_features.h
 
-static struct {
+struct dpi_data {
struct platform_device *pdev;
 
struct regulator *vdds_dsi_reg;
@@ -52,7 +52,45 @@ static struct {
struct omap_dss_device output;
 
bool port_initialized;
-} dpi;
+};
+
+static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device 
*dssdev)
+{
+   struct device_node *parent = dssdev-dev-of_node;
+   struct device_node *port;
+
+   /* non DT */
+   if (!parent) {
+   struct omap_dss_device *out = dssdev-src;
+
+   return dev_get_drvdata(out-dev);
+   }
+
+   port = omapdss_of_get_next_port(parent, NULL);
+   if (!port)
+   return NULL;
+
+   do {
+   int r;
+   u32 reg;
+
+   r = of_property_read_u32(port, reg, reg);
+   if (r)
+   reg = 0;
+
+   if (reg == dssdev-reg)
+   return port-data;
+
+   } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
+
+   return NULL;
+}
+
+/* use only for non DT mode */
+static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
+{
+   return dev_get_drvdata(pdev-dev);
+}
 
 static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
 {
@@ -197,15 +235,16 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
dpi_calc_dispc_cb, ctx);
 }
 
-static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
+static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
+   struct dpi_clk_calc_ctx *ctx)
 {
unsigned long clkin;
unsigned long pll_min, pll_max;
 
-   clkin = dsi_get_pll_clkin(dpi.dsidev);
+   clkin = dsi_get_pll_clkin(dpi-dsidev);
 
memset(ctx, 0, sizeof(*ctx));
-   ctx-dsidev = dpi.dsidev;
+   ctx-dsidev = dpi-dsidev;
ctx-pck_min = pck - 1000;
ctx-pck_max = pck + 1000;
ctx-dsi_cinfo.clkin = clkin;
@@ -213,7 +252,7 @@ static bool dpi_dsi_clk_calc(unsigned long pck, struct 
dpi_clk_calc_ctx *ctx)
pll_min = 0;
pll_max = 0;
 
-   return dsi_pll_calc(dpi.dsidev, clkin,
+   return dsi_pll_calc(dpi-dsidev, clkin,
pll_min, pll_max,
dpi_calc_pll_cb, ctx);
 }
@@ -249,7 +288,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct 
dpi_clk_calc_ctx *ctx)
 
 
 
-static int dpi_set_dsi_clk(enum omap_channel channel,
+static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
 {
@@ -257,18 +296,18 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
int r;
bool ok;
 
-   ok = dpi_dsi_clk_calc(pck_req, ctx);
+   ok = dpi_dsi_clk_calc(dpi, pck_req, ctx);
if (!ok)
return -EINVAL;
 
-   r = dsi_pll_set_clock_div(dpi.dsidev, ctx.dsi_cinfo);
+   r = dsi_pll_set_clock_div(dpi-dsidev, ctx.dsi_cinfo);
if (r)
return r;
 
dss_select_lcd_clk_source(channel,
dpi_get_alt_clk_src(channel));
 
-   dpi.mgr_config.clock_info = ctx.dispc_cinfo;
+   dpi-mgr_config.clock_info = ctx.dispc_cinfo;
 
*fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
*lck_div = ctx.dispc_cinfo.lck_div;
@@ -277,8 +316,8 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
return 0;
 }
 
-static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
-   int *lck_div, int *pck_div)
+static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long

[RFC 6/6] omapdss: DSS: add reg-id param to dpi_select_source

2014-05-08 Thread Archit Taneja
Add an argument which describes which DPI instance we are referring to when
selecting it's overlay manager. This will come into use when a DSS version
supports multiple DPI instances.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/video/fbdev/omap2/dss/dpi.c |  2 +-
 drivers/video/fbdev/omap2/dss/dss.c | 12 ++--
 drivers/video/fbdev/omap2/dss/dss.h |  2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dpi.c 
b/drivers/video/fbdev/omap2/dss/dpi.c
index faf266e..def8e68 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -420,7 +420,7 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
if (r)
goto err_get_dispc;
 
-   r = dss_dpi_select_source(out-manager-id);
+   r = dss_dpi_select_source(out-reg, out-manager-id);
if (r)
goto err_src_sel;
 
diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
index 4087f3b..ffa6d84 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -74,7 +74,7 @@ struct dss_features {
u8 fck_div_max;
u8 dss_fck_multiplier;
const char *parent_clk_name;
-   int (*dpi_select_source)(enum omap_channel channel);
+   int (*dpi_select_source)(int id, enum omap_channel channel);
int (*init_ports)(struct platform_device *pdev);
void (*uninit_ports)(struct platform_device *pdev);
 };
@@ -570,7 +570,7 @@ enum dss_hdmi_venc_clk_source_select 
dss_get_hdmi_venc_clk_source(void)
return REG_GET(DSS_CONTROL, 15, 15);
 }
 
-static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
+static int dss_dpi_select_source_omap2_omap3(int id, enum omap_channel channel)
 {
if (channel != OMAP_DSS_CHANNEL_LCD)
return -EINVAL;
@@ -578,7 +578,7 @@ static int dss_dpi_select_source_omap2_omap3(enum 
omap_channel channel)
return 0;
 }
 
-static int dss_dpi_select_source_omap4(enum omap_channel channel)
+static int dss_dpi_select_source_omap4(int id, enum omap_channel channel)
 {
int val;
 
@@ -598,7 +598,7 @@ static int dss_dpi_select_source_omap4(enum omap_channel 
channel)
return 0;
 }
 
-static int dss_dpi_select_source_omap5(enum omap_channel channel)
+static int dss_dpi_select_source_omap5(int id, enum omap_channel channel)
 {
int val;
 
@@ -624,9 +624,9 @@ static int dss_dpi_select_source_omap5(enum omap_channel 
channel)
return 0;
 }
 
-int dss_dpi_select_source(enum omap_channel channel)
+int dss_dpi_select_source(int id, enum omap_channel channel)
 {
-   return dss.feat-dpi_select_source(channel);
+   return dss.feat-dpi_select_source(id, channel);
 }
 
 static int dss_get_clocks(void)
diff --git a/drivers/video/fbdev/omap2/dss/dss.h 
b/drivers/video/fbdev/omap2/dss/dss.h
index 6f68f72..f3ddcc9 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -209,7 +209,7 @@ int dss_init_platform_driver(void) __init;
 void dss_uninit_platform_driver(void);
 
 unsigned long dss_get_dispc_clk_rate(void);
-int dss_dpi_select_source(enum omap_channel channel);
+int dss_dpi_select_source(int id, enum omap_channel channel);
 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ARM: OMAP5: DSS hwmod data

2014-05-07 Thread Archit Taneja

Hi Paul,

On Thursday 08 May 2014 10:07 AM, Paul Walmsley wrote:

Hi,

On Wed, 12 Mar 2014, Tomi Valkeinen wrote:


This patch adds hwmod data for omap5 display subsystem. I have tested this on
omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the
mainline is missing omap5 HDMI driver.

I do see this when booting:

   omap_hwmod: dss_dispc: cannot be enabled for reset (3)
   omap_hwmod: dss_dsi1: cannot be enabled for reset (3)
   omap_hwmod: dss_dsi2: cannot be enabled for reset (3)
   omap_hwmod: dss_hdmi: cannot be enabled for reset (3)
   omap_hwmod: dss_rfbi: cannot be enabled for reset (3)

But at least DSI works just fine.


Am looking at this for v3.16.  But I think someone needs to take a look at
those warnings and figure out why they are happening.


We associate DSS clock domain's MODULEMODE bits only with the dss_core 
hwmod. The rest of the dss hwmods don't touch MODULEMODE.


Therefore, these hwmods cannot be enabled independently, and reset.

We don't face this issue in the omapdss driver since the platform 
devices corresponding to these hwmods have their parent as the platform 
device corresponding to 'dss_core'. This parent child-relation ensures 
that 'dss_core' is enabled when the a child calls a pm_runtime_get function.


The problem is that we have multiple hwmods which use the same 
MODULEMODE bit. There is no use-counting done when it comes to 
enabling/disabling modulemode. If there was such a thing, we could have 
provided MODULEMODE flags even for the children hwmods.




Is the soc_ops.wait_target_ready() call failing in omap_hwmod.c:_enable()
?


Yes, that's the one that fails.

We have the same DSS in OMAP4, but we don't see the issue there. That's 
because we have modeled the MODULEMODE bits as a fake interface clock. 
That lets us enable hwmods independently, but it messes up DSS PM as it 
breaks some rules related to the sequence in which the opt-clocks and 
MODULEMODE bits need to be disabled.


We would want to change OMAP4 to work the way as above too, with the 
cost of having these prints above.


Archit



--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 2/4] ARM: dts: Add ctrl-core DT node for DRA7

2014-05-05 Thread Archit Taneja

Hi,

On Monday 21 April 2014 08:40 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140420 22:16]:

Hi,

On Friday 18 April 2014 10:48 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140416 06:20]:

Add DT node for the ctrl-core sub module of the DRA7 control module. We map the
CTRL_MODULE_CORE address region up to 0x4a002d60, this region contains register
fields which configure clocks. The remainder of the registers are related to
pad configurations or cross-bar configurations, and therefore aren't mapped.


Can you please check if this can just use the existing
regmap syscon mapping:

syscon = dra7_ctrl_general;

See how the drivers/regulator/pbias-regulator.c is using the
syscon to initialize a regulator and then omap_hsmmc.c just does
the standard regulator calls.


The thing is that this bit needs to be set before the the DSS hwmods are
reset, and that happens very early. If we don't do this, DSS won't reset
properly, and not get back to an idle state.

I am not sure where I can configure the syscon register early enough that it
happens before the hwmods are reset. With a syscon mapping, I guess we would
access the register when the DSS driver is probed. But that's too late for
us.

Ideally, it would be much better to have a syscon mapping. Do you have any
suggestions how this can be achieved very early in boot?


It's best to move the reset and initialization of DSS happen later. I believe
we already are resetting only some of the hwmods early on.



I looked at this in some more detail. With the current hwmod 
flags(HWMOD_INIT_NO_RESET/NO_IDLE), we still try to enable the IP, it's 
just the reset part(ocp reset/custom reset and sysc register) or the 
disable part that is skipped. hwmod still tries to enable the IP.


This again results in the same issue.

One thing which wasn't clear was that why do we enable a hwmod in the 
first place, if we know that we are going to skip reset?


Archit


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 01/23] OMAPDSS: HDMI: lane config support

2014-04-25 Thread Archit Taneja

Hi,

On Thursday 24 April 2014 03:46 PM, Tomi Valkeinen wrote:

Add support to configure the pins used for the HDMI lanes. The order and
polarity of the lanes can be defined in the DT data.

Signed-off-by: Tomi Valkeinen tomi.valkei...@ti.com
---



+static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy)
+{
+   static const u16 pad_cfg_list[] = {
+   0x0123,
+   0x0132,
+   0x0312,
+   0x0321,
+   0x0231,
+   0x0213,
+   0x1023,
+   0x1032,
+   0x3012,
+   0x3021,
+   0x2031,
+   0x2013,
+   0x1203,
+   0x1302,
+   0x3102,
+   0x3201,
+   0x2301,
+   0x2103,
+   0x1230,
+   0x1320,
+   0x3120,
+   0x3210,
+   0x2310,
+   0x2130,
+   };
+
+   u16 lane_cfg = 0;
+   int i;
+   unsigned lane_cfg_val;
+   u16 pol_val = 0;
+
+   for (i = 0; i  4; ++i)
+   lane_cfg |= phy-lane_function[i]  ((3 - i) * 4);
+
+   pol_val |= phy-lane_polarity[0]  0;
+   pol_val |= phy-lane_polarity[1]  3;
+   pol_val |= phy-lane_polarity[2]  2;
+   pol_val |= phy-lane_polarity[3]  1;
+
+   for (i = 0; i  ARRAY_SIZE(pad_cfg_list); ++i)
+   if (pad_cfg_list[i] == lane_cfg)
+   break;
+
+   if (WARN_ON(i == ARRAY_SIZE(pad_cfg_list)))
+   i = 0;
+
+   lane_cfg_val = i;


I spent some time to see if we could get create lane_cfg_val without 
having the table above, looks like there is no pattern at all in the 
register field.



+
+   REG_FLD_MOD(phy-base, HDMI_TXPHY_PAD_CFG_CTRL, lane_cfg_val, 26, 22);
+   REG_FLD_MOD(phy-base, HDMI_TXPHY_PAD_CFG_CTRL, pol_val, 30, 27);
+}
+
  int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp,
struct hdmi_config *cfg)
  {
@@ -92,8 +183,7 @@ int hdmi_phy_enable(struct hdmi_phy_data *phy, struct 
hdmi_wp_data *wp,
/* Setup max LDO voltage */
REG_FLD_MOD(phy-base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);

-   /* Write to phy address 3 to change the polarity control */
-   REG_FLD_MOD(phy-base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);


wow, didn't realize it was hardcoded like this.

Reviewed-by: Archit Taneja arc...@ti.com?

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 06/23] ARM: OMAP: add OMAP5 DSI muxing

2014-04-25 Thread Archit Taneja

Hi,

On Thursday 24 April 2014 03:47 PM, Tomi Valkeinen wrote:

Add support to set OMAP5 DSI pin muxing.

Signed-off-by: Tomi Valkeinen tomi.valkei...@ti.com
Cc: Tony Lindgren t...@atomide.com
---
  arch/arm/mach-omap2/display.c | 35 ++-
  1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 16d33d831287..974461441fc3 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -137,11 +137,42 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
return 0;
  }

+#define CONTROL_PAD_BASE   0x4A002800
+#define CONTROL_DSIPHY 0x614
+


I guess this is something we can move to our driver, and use sysconf to 
get the register from DT.


Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 06/23] ARM: OMAP: add OMAP5 DSI muxing

2014-04-25 Thread Archit Taneja

On Friday 25 April 2014 04:48 PM, Tomi Valkeinen wrote:

On 25/04/14 14:11, Archit Taneja wrote:

Hi,

On Thursday 24 April 2014 03:47 PM, Tomi Valkeinen wrote:

Add support to set OMAP5 DSI pin muxing.

Signed-off-by: Tomi Valkeinen tomi.valkei...@ti.com
Cc: Tony Lindgren t...@atomide.com
---
   arch/arm/mach-omap2/display.c | 35 ++-
   1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c
b/arch/arm/mach-omap2/display.c
index 16d33d831287..974461441fc3 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -137,11 +137,42 @@ static int omap4_dsi_mux_pads(int dsi_id,
unsigned lanes)
   return 0;
   }

+#define CONTROL_PAD_BASE0x4A002800
+#define CONTROL_DSIPHY0x614
+


I guess this is something we can move to our driver, and use sysconf to
get the register from DT.


I just copied the same method as used for OMAP4.

I guess sysconf is an option. But I really dislike the idea of moving
omap control module code to a display driver... I'm not sure what other
options we have, though. Maybe an OMAP DSI specific pinctrl driver?


OMAP4 has CONTROL_DSIPHY for configuring both lane enable/disbale, and 
pull up/down, but OMAP5 has normal PAD_CONF registers for DSI lines(2 
pins per register) for configuring pull up/down, and CONTROL_DSIPHY for 
lane enable/disable.


We would have a very messed up pinctrl driver, but it would probably be 
better than doing all this stuff in the driver.


Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 2/4] ARM: dts: Add ctrl-core DT node for DRA7

2014-04-20 Thread Archit Taneja

Hi,

On Friday 18 April 2014 10:48 PM, Tony Lindgren wrote:

* Archit Taneja arc...@ti.com [140416 06:20]:

Add DT node for the ctrl-core sub module of the DRA7 control module. We map the
CTRL_MODULE_CORE address region up to 0x4a002d60, this region contains register
fields which configure clocks. The remainder of the registers are related to
pad configurations or cross-bar configurations, and therefore aren't mapped.


Can you please check if this can just use the existing
regmap syscon mapping:

syscon = dra7_ctrl_general;

See how the drivers/regulator/pbias-regulator.c is using the
syscon to initialize a regulator and then omap_hsmmc.c just does
the standard regulator calls.


The thing is that this bit needs to be set before the the DSS hwmods are 
reset, and that happens very early. If we don't do this, DSS won't reset 
properly, and not get back to an idle state.


I am not sure where I can configure the syscon register early enough 
that it happens before the hwmods are reset. With a syscon mapping, I 
guess we would access the register when the DSS driver is probed. But 
that's too late for us.


Ideally, it would be much better to have a syscon mapping. Do you have 
any suggestions how this can be achieved very early in boot?


Archit



Depending what the range 0x4a002000 0x6d0 contains, you may
want to set it up as another syscon area.

Regards,

Tony


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 3/4] ARM: dts: Add dss_deshdcp clock node under dra7-ctrl-core

2014-04-16 Thread Archit Taneja
The DESHDCP clock is required only by the DES-HDCP block within HDMI in DSS.
However, if the clock isn't set before DSS clock domian is enabled, the clock
domain never comes out of idle state.

The DESHDCP clock is enabled/disabled at the DSS boundary by the bit
DSS_DESHDCP_CLKEN in CTRL_CORE_CONTROL_IO_2.

Add dss_deshdcp gate-clock node under dra7-ctrl-core. There are separate bit
fields for enabling and disabling the clock. We just map the enable bit since
this clock doesn't cause any impact if left enabled.

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/boot/dts/dra7xx-clocks.dtsi | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi 
b/arch/arm/boot/dts/dra7xx-clocks.dtsi
index e96da9a..78d309c 100644
--- a/arch/arm/boot/dts/dra7xx-clocks.dtsi
+++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi
@@ -2007,6 +2007,16 @@
};
 };
 
+ctrl_core_clocks {
+   dss_deshdcp_clk: dss_deshdcp_clk {
+   #clock-cells = 0;
+   compatible = ti,gate-clock;
+   clocks = l3_iclk_div;
+   ti,bit-shift = 0;
+   reg = 0x0558;
+   };
+};
+
 cm_core_clockdomains {
coreaon_clkdm: coreaon_clkdm {
compatible = ti,clockdomain;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 4/4] CLK: TI: Enable dss_deshdcp clock in dra7xx_clk_init

2014-04-16 Thread Archit Taneja
The DESHDCP clock is required only by the DES-HDCP block within HDMI in DSS.
However, if the clock isn't set before DSS clock domian is enabled, the clock
domain never comes out of idle state.

This is because the DSS IP is designed in such a way that if DES-HDCP block
can't transition from idle state, the entire DSS clock domain also cannot
transition from idle to enabled. DES-HDCP block needs the DESHDCP clock
enabled to transition from idle successfully.

We enable the deshdcp clock in dra7xx_clk_init() which happens before omap
hwmods are setup. This clock is effectively a gate clock with the parent as
DSS_L3_GICLK. The parent is an automatically controlled clock by DSS clock
domain and hence doesn't have a clock node associated to it. Since
DSS_L3_GICLK is derived from the OCP clock, we set the dss_deshdcp_clk's
parent as l3_iclk_div.

Leaving this bit enabled doesn't prevent DSS or the system to suspend, and only
a very few flops get this clock all the time. So there is negligible impact.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/clk/ti/clk-7xx.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c
index f7e4073..3f73a02 100644
--- a/drivers/clk/ti/clk-7xx.c
+++ b/drivers/clk/ti/clk-7xx.c
@@ -179,6 +179,7 @@ static struct ti_dt_clk dra7xx_clks[] = {
DT_CLK(NULL, dss_hdmi_clk, dss_hdmi_clk),
DT_CLK(NULL, dss_video1_clk, dss_video1_clk),
DT_CLK(NULL, dss_video2_clk, dss_video2_clk),
+   DT_CLK(NULL, dss_deshdcp_clk, dss_deshdcp_clk),
DT_CLK(NULL, gpio1_dbclk, gpio1_dbclk),
DT_CLK(NULL, gpio2_dbclk, gpio2_dbclk),
DT_CLK(NULL, gpio3_dbclk, gpio3_dbclk),
@@ -306,7 +307,7 @@ static struct ti_dt_clk dra7xx_clks[] = {
 int __init dra7xx_dt_clk_init(void)
 {
int rc;
-   struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck;
+   struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *dss_deshdcp_ck;
 
ti_dt_clocks_register(dra7xx_clks);
 
@@ -327,5 +328,10 @@ int __init dra7xx_dt_clk_init(void)
if (rc)
pr_err(%s: failed to configure GMAC DPLL!\n, __func__);
 
+   dss_deshdcp_ck = clk_get_sys(NULL, dss_deshdcp_clk);
+   rc = clk_prepare_enable(dss_deshdcp_ck);
+   if (rc)
+   pr_err(%s: failed to enable DESHDCP clock\n, __func__);
+
return rc;
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 2/4] ARM: dts: Add ctrl-core DT node for DRA7

2014-04-16 Thread Archit Taneja
Add DT node for the ctrl-core sub module of the DRA7 control module. We map the
CTRL_MODULE_CORE address region up to 0x4a002d60, this region contains register
fields which configure clocks. The remainder of the registers are related to
pad configurations or cross-bar configurations, and therefore aren't mapped.

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/boot/dts/dra7.dtsi | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 1c0f8e1..58bbdf3 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -148,6 +148,19 @@
};
};
 
+   ctrl_core: ctrl_core@4a002000 {
+   compatible = ti,dra7-ctrl-core;
+   reg = 0x4a002000 0x6d0;
+
+   ctrl_core_clocks: clocks {
+   #address-cells = 1;
+   #size-cells = 0;
+   };
+
+   ctrl_core_clockdomains: clockdomains {
+   };
+   };
+
counter32k: counter@4ae04000 {
compatible = ti,omap-counter32k;
reg = 0x4ae04000 0x40;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 1/4] ARM: OMAP2+: Add CTRL_MODULE_CORE as a master clock provider for DRA7

2014-04-16 Thread Archit Taneja
The control module isn't actually a clock management module, but there are a few
register bits which perform gating and muxing of clocks.

Add CTRL_MODULE_CORE sub block as a clock provider for DRA7. The control module
has 2 sub modules: CTRL_MODULE_CORE, and CTRL_MODULE_WKUP. Out of these, only
the CORE sub module has clock related register fields. We ignore the WKUP sub
module.

Signed-off-by: Archit Taneja arc...@ti.com
---
 arch/arm/mach-omap2/prm_common.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index b4c4ab9..f86029a 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -489,6 +489,7 @@ static struct of_device_id omap_prcm_dt_match_table[] = {
{ .compatible = ti,dra7-prm },
{ .compatible = ti,dra7-cm-core-aon },
{ .compatible = ti,dra7-cm-core },
+   { .compatible = ti,dra7-ctrl-core },
{ }
 };
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/14] v4l: ti-vpe: Rename csc memory resource name

2014-03-14 Thread Archit Taneja

Hi Kamil,

On Thursday 13 March 2014 08:14 PM, Kamil Debski wrote:

Hi,


From: Archit Taneja [mailto:arc...@ti.com]
Sent: Thursday, March 13, 2014 12:44 PM

Rename the memory block resource vpe_csc to csc since it also
exists within the VIP IP block. This would make the name more generic,
and both VPE and VIP DT nodes in the future can use it.


I understand that this is not yet used in any public dts files. Right?

Best wishes,



Yes, a VPE DT node doesn't exist in any public dts files yet. So it's 
safe to change the name.


It should eventually come in dra7.dtsi. There is a dependency on a 
crossbar IP module, which provides us with an IRQ line for VPE going to 
the GIC. Once that is merged, I can add the VPE DT node.


Thanks,
Archit


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 02/14] v4l: ti-vpe: register video device only when firmware is loaded

2014-03-14 Thread Archit Taneja

Hi,

On Thursday 13 March 2014 07:59 PM, Kamil Debski wrote:

Hi,


From: Archit Taneja [mailto:arc...@ti.com]
Sent: Thursday, March 13, 2014 1:09 PM

Hi Kamil,

On Thursday 13 March 2014 05:18 PM, Kamil Debski wrote:

Hi Archit,


From: Archit Taneja [mailto:arc...@ti.com]
Sent: Tuesday, March 11, 2014 9:34 AM

vpe fops(vpe_open in particular) should be called only when VPDMA
firmware is loaded. File operations on the video device are possible
the moment it is registered.

Currently, we register the video device for VPE at driver probe,
after calling a vpdma helper to initialize VPDMA and load firmware.
This function is non-blocking(it calls request_firmware_nowait()),
and doesn't ensure that the firmware is actually loaded when it

returns.


We remove the device registration from vpe probe, and move it to a
callback provided by the vpe driver to the vpdma library, through
vpdma_create().

The ready field in vpdma_data is no longer needed since we always
have firmware loaded before the device is registered.

A minor problem with this approach is that if the
video_register_device fails(which doesn't really happen), the vpe
platform device would be registered.
however, there won't be any v4l2 device corresponding to it.


Could you explain to me one thing. request_firmware cannot be used in
probe, thus you are using request_firmware_nowait. Why cannot the
firmware be loaded on open with a regular request_firmware that is
waiting?


I totally agree with you here. Placing the firmware in open() would
probably make more sense.

The reason I didn't place it in open() is because I didn't want to
release firmware in a corresponding close(), and be in a situation
where the firmware is loaded multiple times in the driver's lifetime.


Would it be possible to load firmware in open and release it in remove?
I know that this would disturb the symmetry between open-release and
probe-remove. But this could work.


That might work.

Currently, the driver doesn't do any clock management, it just enables 
the clocks in probe, and disables them in remove. I need to check how 
the firmware is dependent on clocks. We could make a better decision 
about where to release the firmware with that information.


Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 00/14] v4l: ti-vpe: Some VPE fixes and enhancements

2014-03-13 Thread Archit Taneja
This patch set mainly consists of minor fixes for the VPE driver. These fixes
ensure the following:

- The VPE module can be inserted and removed successively.
- Make sure that smaller resolutions like qcif work correctly.
- Prevent race condition between firmware loading and an open call to the v4l2
  device.
- Prevent the possibility of output m2m queue not having sufficient 'ready'
  buffers.
- Some VPDMA data descriptor fields weren't understood correctly before. They
  are now used correctly.

The rest of the patches add some minor features like DMA buf support and
cropping/composing.

Reference branch:

g...@github.com:boddob/linux.git vpe_for_315

Changes in v4:

- More legible code for selection API
- Stricter checking for target type vs crop type in g_selection
- Minor fix in patch 13/14, there was a logical bug in buf_prepare when
  checking validity of top and bottom fields.

Changes in v3:

- improvements in selection API patch.
- querycap fixes for v4l2 compliance.
- v4l2_buffer 'field' and flags' fixes for compliance.
- fixes in try_fmt vpe_open for compliance.
- rename a IOMEM resource for better DT compatibility.

Changes in v2:

- selection API used instead of older cropping API.
- Typo fix.
- Some changes in patch 6/7 to support composing on the capture side of VPE.


Archit Taneja (14):
  v4l: ti-vpe: Make sure in job_ready that we have the needed number of
dst_bufs
  v4l: ti-vpe: register video device only when firmware is loaded
  v4l: ti-vpe: Use video_device_release_empty
  v4l: ti-vpe: Allow DMABUF buffer type support
  v4l: ti-vpe: Allow usage of smaller images
  v4l: ti-vpe: Fix some params in VPE data descriptors
  v4l: ti-vpe: Add selection API in VPE driver
  v4l: ti-vpe: Rename csc memory resource name
  v4l: ti-vpe: report correct capabilities in querycap
  v4l: ti-vpe: Use correct bus_info name for the device in querycap
  v4l: ti-vpe: Fix initial configuration queue data
  v4l: ti-vpe: zero out reserved fields in try_fmt
  v4l: ti-vpe: Set correct field parameter for output and capture
buffers
  v4l: ti-vpe: retain v4l2_buffer flags for captured buffers

 drivers/media/platform/ti-vpe/csc.c   |   2 +-
 drivers/media/platform/ti-vpe/vpdma.c |  68 ++---
 drivers/media/platform/ti-vpe/vpdma.h |  17 ++-
 drivers/media/platform/ti-vpe/vpe.c   | 272 --
 4 files changed, 290 insertions(+), 69 deletions(-)

-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 14/14] v4l: ti-vpe: retain v4l2_buffer flags for captured buffers

2014-03-13 Thread Archit Taneja
The dequed CAPTURE_MPLANE type buffers don't contain the flags that the
originally queued OUTPUT_MPLANE type buffers have. This breaks compliance.

Copy the source v4l2_buffer flags to the destination v4l2_buffer flags before
they are dequed.

Reviewed-by: Hans Verkuil hans.verk...@cisco.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 362d5be..972f43f 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1288,13 +1288,12 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
s_buf = s_vb-v4l2_buf;
d_buf = d_vb-v4l2_buf;
 
+   d_buf-flags = s_buf-flags;
+
d_buf-timestamp = s_buf-timestamp;
-   d_buf-flags = ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
-   d_buf-flags |= s_buf-flags  V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
-   if (s_buf-flags  V4L2_BUF_FLAG_TIMECODE) {
-   d_buf-flags |= V4L2_BUF_FLAG_TIMECODE;
+   if (s_buf-flags  V4L2_BUF_FLAG_TIMECODE)
d_buf-timecode = s_buf-timecode;
-   }
+
d_buf-sequence = ctx-sequence;
 
d_q_data = ctx-q_data[Q_DATA_DST];
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 12/14] v4l: ti-vpe: zero out reserved fields in try_fmt

2014-03-13 Thread Archit Taneja
Zero out the reserved formats in v4l2_pix_format_mplane and
v4l2_plane_pix_format members of the returned v4l2_format pointer when passed
through TRY_FMT ioctl.

This ensures that the user doesn't interpret the non-zero fields as some data
passed by the driver, and ensures compliance.

Reviewed-by: Hans Verkuil hans.verk...@cisco.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index d7befb9..c0ae847 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1488,6 +1488,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct 
v4l2_format *f,
}
}
 
+   memset(pix-reserved, 0, sizeof(pix-reserved));
for (i = 0; i  pix-num_planes; i++) {
plane_fmt = pix-plane_fmt[i];
depth = fmt-vpdma_fmt[i]-depth;
@@ -1499,6 +1500,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct 
v4l2_format *f,
 
plane_fmt-sizeimage =
(pix-height * pix-width * depth)  3;
+
+   memset(plane_fmt-reserved, 0, sizeof(plane_fmt-reserved));
}
 
return 0;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 02/14] v4l: ti-vpe: register video device only when firmware is loaded

2014-03-13 Thread Archit Taneja
vpe fops(vpe_open in particular) should be called only when VPDMA firmware
is loaded. File operations on the video device are possible the moment it is
registered.

Currently, we register the video device for VPE at driver probe, after calling
a vpdma helper to initialize VPDMA and load firmware. This function is
non-blocking(it calls request_firmware_nowait()), and doesn't ensure that the
firmware is actually loaded when it returns.

We remove the device registration from vpe probe, and move it to a callback
provided by the vpe driver to the vpdma library, through vpdma_create().

The ready field in vpdma_data is no longer needed since we always have firmware
loaded before the device is registered.

A minor problem with this approach is that if the video_register_device
fails(which doesn't really happen), the vpe platform device would be registered.
however, there won't be any v4l2 device corresponding to it.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpdma.c |  8 +++--
 drivers/media/platform/ti-vpe/vpdma.h |  7 +++--
 drivers/media/platform/ti-vpe/vpe.c   | 55 ---
 3 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c 
b/drivers/media/platform/ti-vpe/vpdma.c
index e8175e7..73dd38e 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -781,7 +781,7 @@ static void vpdma_firmware_cb(const struct firmware *f, 
void *context)
/* already initialized */
if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
VPDMA_LIST_RDY_SHFT)) {
-   vpdma-ready = true;
+   vpdma-cb(vpdma-pdev);
return;
}
 
@@ -811,7 +811,7 @@ static void vpdma_firmware_cb(const struct firmware *f, 
void *context)
goto free_buf;
}
 
-   vpdma-ready = true;
+   vpdma-cb(vpdma-pdev);
 
 free_buf:
vpdma_unmap_desc_buf(vpdma, fw_dma_buf);
@@ -839,7 +839,8 @@ static int vpdma_load_firmware(struct vpdma_data *vpdma)
return 0;
 }
 
-struct vpdma_data *vpdma_create(struct platform_device *pdev)
+struct vpdma_data *vpdma_create(struct platform_device *pdev,
+   void (*cb)(struct platform_device *pdev))
 {
struct resource *res;
struct vpdma_data *vpdma;
@@ -854,6 +855,7 @@ struct vpdma_data *vpdma_create(struct platform_device 
*pdev)
}
 
vpdma-pdev = pdev;
+   vpdma-cb = cb;
 
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, vpdma);
if (res == NULL) {
diff --git a/drivers/media/platform/ti-vpe/vpdma.h 
b/drivers/media/platform/ti-vpe/vpdma.h
index cf40f11..bf5f8bb 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -35,8 +35,8 @@ struct vpdma_data {
 
struct platform_device  *pdev;
 
-   /* tells whether vpdma firmware is loaded or not */
-   bool ready;
+   /* callback to VPE driver when the firmware is loaded */
+   void (*cb)(struct platform_device *pdev);
 };
 
 enum vpdma_data_format_type {
@@ -208,6 +208,7 @@ void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
 void vpdma_dump_regs(struct vpdma_data *vpdma);
 
 /* initialize vpdma, passed with VPE's platform device pointer */
-struct vpdma_data *vpdma_create(struct platform_device *pdev);
+struct vpdma_data *vpdma_create(struct platform_device *pdev,
+   void (*cb)(struct platform_device *pdev));
 
 #endif
diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index f3143ac..f1eae67 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1817,11 +1817,6 @@ static int vpe_open(struct file *file)
 
vpe_dbg(dev, vpe_open\n);
 
-   if (!dev-vpdma-ready) {
-   vpe_err(dev, vpdma firmware not loaded\n);
-   return -ENODEV;
-   }
-
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
@@ -2039,10 +2034,40 @@ static void vpe_runtime_put(struct platform_device 
*pdev)
WARN_ON(r  0  r != -ENOSYS);
 }
 
+static void vpe_fw_cb(struct platform_device *pdev)
+{
+   struct vpe_dev *dev = platform_get_drvdata(pdev);
+   struct video_device *vfd;
+   int ret;
+
+   vfd = dev-vfd;
+   *vfd = vpe_videodev;
+   vfd-lock = dev-dev_mutex;
+   vfd-v4l2_dev = dev-v4l2_dev;
+
+   ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+   if (ret) {
+   vpe_err(dev, Failed to register video device\n);
+
+   vpe_set_clock_enable(dev, 0);
+   vpe_runtime_put(pdev);
+   pm_runtime_disable(pdev-dev);
+   v4l2_m2m_release(dev-m2m_dev);
+   vb2_dma_contig_cleanup_ctx(dev-alloc_ctx);
+   v4l2_device_unregister(dev-v4l2_dev);
+
+   return;
+   }
+
+   video_set_drvdata

[PATCH v4 10/14] v4l: ti-vpe: Use correct bus_info name for the device in querycap

2014-03-13 Thread Archit Taneja
The bus_info parameter in v4l2_capabilities expects a 'platform_' prefix. This
wasn't done in the driver and hence was breaking compliance. Update the bus_info
parameter accordingly.

Reviewed-by: Hans Verkuil hans.verk...@cisco.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index c066eb8..3a312ea 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1346,7 +1346,8 @@ static int vpe_querycap(struct file *file, void *priv,
 {
strncpy(cap-driver, VPE_MODULE_NAME, sizeof(cap-driver) - 1);
strncpy(cap-card, VPE_MODULE_NAME, sizeof(cap-card) - 1);
-   strlcpy(cap-bus_info, VPE_MODULE_NAME, sizeof(cap-bus_info));
+   snprintf(cap-bus_info, sizeof(cap-bus_info), platform:%s,
+   VPE_MODULE_NAME);
cap-device_caps  = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
cap-capabilities = cap-device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 06/14] v4l: ti-vpe: Fix some params in VPE data descriptors

2014-03-13 Thread Archit Taneja
Some parameters of the VPE descriptors were understood incorrectly. They are now
fixed. The fixes are explained as follows:

- When adding an inbound data descriptor to the VPDMA descriptor list, we intend
  to use c_rect as the cropped region fetched by VPDMA. Therefore, c_rect-width
  shouldn't be used to calculate the line stride, the original image width
  should be used for that. We add a 'width' argument which gives the buffer
  width in memory.

- frame_width and frame_height describe the complete width and height of the
  client to which the channel is connected. If there are multiple channels
  fetching data and providing to the same client, the above 2 arguments should
  be the width and height of the region covered by all the channels. In the case
  where there is only one channel providing pixel data to the client
  (like in VPE), frame_width and frame_height should be the cropped width and
  cropped height respectively. The calculation of these params is done in the
  vpe driver now.

- start_h and start_v is also used in the case of multiple channels to describe
  where each channel should start filling pixel data. We don't use this in VPE,
  and pass 0s to the vpdma_add_in_dtd() helper.

- Some minor changes are made to the vpdma_add_out_dtd() helper. The c_rect
  param is used for specifying the 'composition' target, and 'width'  is added
  to calculate the line stride.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpdma.c | 60 +++
 drivers/media/platform/ti-vpe/vpdma.h | 10 +++---
 drivers/media/platform/ti-vpe/vpe.c   | 18 +++
 3 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c 
b/drivers/media/platform/ti-vpe/vpdma.c
index 73dd38e..a51a013 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -614,8 +614,17 @@ static void dump_dtd(struct vpdma_dtd *dtd)
 /*
  * append an outbound data transfer descriptor to the given descriptor list,
  * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel
+ *
+ * @list: vpdma desc list to which we add this decriptor
+ * @width: width of the image in pixels in memory
+ * @c_rect: compose params of output image
+ * @fmt: vpdma data format of the buffer
+ * dma_addr: dma address as seen by VPDMA
+ * chan: VPDMA channel
+ * flags: VPDMA flags to configure some descriptor fileds
  */
-void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
+void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
+   const struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
enum vpdma_channel chan, u32 flags)
 {
@@ -623,6 +632,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct 
v4l2_rect *c_rect,
int field = 0;
int notify = 1;
int channel, next_chan;
+   struct v4l2_rect rect = *c_rect;
int depth = fmt-depth;
int stride;
struct vpdma_dtd *dtd;
@@ -630,11 +640,15 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, 
struct v4l2_rect *c_rect,
channel = next_chan = chan_info[chan].num;
 
if (fmt-type == VPDMA_DATA_FMT_TYPE_YUV 
-   fmt-data_type == DATA_TYPE_C420)
+   fmt-data_type == DATA_TYPE_C420) {
+   rect.height = 1;
+   rect.top = 1;
depth = 8;
+   }
 
-   stride = ALIGN((depth * c_rect-width)  3, VPDMA_STRIDE_ALIGN);
-   dma_addr += (c_rect-left * depth)  3;
+   stride = ALIGN((depth * width)  3, VPDMA_STRIDE_ALIGN);
+
+   dma_addr += rect.top * stride + (rect.left * depth  3);
 
dtd = list-next;
WARN_ON((void *)(dtd + 1)  (list-buf.addr + list-buf.size));
@@ -664,31 +678,48 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, 
struct v4l2_rect *c_rect,
 /*
  * append an inbound data transfer descriptor to the given descriptor list,
  * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel
+ *
+ * @list: vpdma desc list to which we add this decriptor
+ * @width: width of the image in pixels in memory(not the cropped width)
+ * @c_rect: crop params of input image
+ * @fmt: vpdma data format of the buffer
+ * dma_addr: dma address as seen by VPDMA
+ * chan: VPDMA channel
+ * field: top or bottom field info of the input image
+ * flags: VPDMA flags to configure some descriptor fileds
+ * frame_width/height: the complete width/height of the image presented to the
+ * client (this makes sense when multiple channels are
+ * connected to the same client, forming a larger frame)
+ * start_h, start_v: position where the given channel starts providing pixel
+ * data to the client (makes sense when multiple channels
+ * contribute to the client)
  */
-void vpdma_add_in_dtd(struct

[PATCH v4 03/14] v4l: ti-vpe: Use video_device_release_empty

2014-03-13 Thread Archit Taneja
The video_device struct is currently embedded in the driver data struct vpe_dev.
A vpe_dev instance is allocated by the driver, and the memory for the vfd is a
part of this struct.

The v4l2 core, however, manages the removal of the vfd region, through the
video_device's .release() op, which currently is the helper
video_device_release. This causes memory corruption, and leads to issues when
we try to re-insert the vpe module.

Use the video_device_release_empty helper function instead.

Reviewed-by: Hans Verkuil hans.verk...@cisco.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index f1eae67..0363df6 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2000,7 +2000,7 @@ static struct video_device vpe_videodev = {
.fops   = vpe_fops,
.ioctl_ops  = vpe_ioctl_ops,
.minor  = -1,
-   .release= video_device_release,
+   .release= video_device_release_empty,
.vfl_dir= VFL_DIR_M2M,
 };
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 09/14] v4l: ti-vpe: report correct capabilities in querycap

2014-03-13 Thread Archit Taneja
querycap currently returns V4L2_CAP_VIDEO_M2M as a capability, this should be
V4L2_CAP_VIDEO_M2M_MPLANE instead, as the driver supports multiplanar formats.

Reviewed-by: Hans Verkuil hans.verk...@cisco.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index f3f1c10..c066eb8 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1347,7 +1347,7 @@ static int vpe_querycap(struct file *file, void *priv,
strncpy(cap-driver, VPE_MODULE_NAME, sizeof(cap-driver) - 1);
strncpy(cap-card, VPE_MODULE_NAME, sizeof(cap-card) - 1);
strlcpy(cap-bus_info, VPE_MODULE_NAME, sizeof(cap-bus_info));
-   cap-device_caps  = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
+   cap-device_caps  = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
cap-capabilities = cap-device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 13/14] v4l: ti-vpe: Set correct field parameter for output and capture buffers

2014-03-13 Thread Archit Taneja
The vpe driver wasn't setting the correct field parameter for dequed CAPTURE
type buffers for the case where the captured output is progressive.

Set the field to V4L2_FIELD_NONE for the completed destination buffers when
the captured output is progressive.

For OUTPUT type buffers, a queued buffer's field is forced to V4L2_FIELD_NONE
if the pixel format(configured through s_fmt for the buffer type
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE specifies) the field type isn't interlaced.
If the pixel format specified was V4L2_FIELD_ALTERNATE, and the queued buffer's
field isn't V4L2_FIELD_TOP or V4L2_FIELD_BOTTOM, the vb2 buf_prepare op returns
an error.

This ensures compliance, and that the dequeued output and captured buffers
contain the field type that the driver used internally.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index c0ae847..362d5be 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1296,10 +1296,10 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
d_buf-timecode = s_buf-timecode;
}
d_buf-sequence = ctx-sequence;
-   d_buf-field = ctx-field;
 
d_q_data = ctx-q_data[Q_DATA_DST];
if (d_q_data-flags  Q_DATA_INTERLACED) {
+   d_buf-field = ctx-field;
if (ctx-field == V4L2_FIELD_BOTTOM) {
ctx-sequence++;
ctx-field = V4L2_FIELD_TOP;
@@ -1308,6 +1308,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
ctx-field = V4L2_FIELD_BOTTOM;
}
} else {
+   d_buf-field = V4L2_FIELD_NONE;
ctx-sequence++;
}
 
@@ -1880,6 +1881,16 @@ static int vpe_buf_prepare(struct vb2_buffer *vb)
q_data = get_q_data(ctx, vb-vb2_queue-type);
num_planes = q_data-fmt-coplanar ? 2 : 1;
 
+   if (vb-vb2_queue-type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+   if (!(q_data-flags  Q_DATA_INTERLACED)) {
+   vb-v4l2_buf.field = V4L2_FIELD_NONE;
+   } else {
+   if (vb-v4l2_buf.field != V4L2_FIELD_TOP 
+   vb-v4l2_buf.field != V4L2_FIELD_BOTTOM)
+   return -EINVAL;
+   }
+   }
+
for (i = 0; i  num_planes; i++) {
if (vb2_plane_size(vb, i)  q_data-sizeimage[i]) {
vpe_err(ctx-dev,
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 11/14] v4l: ti-vpe: Fix initial configuration queue data

2014-03-13 Thread Archit Taneja
The vpe output and capture queues are initially configured to default values in
vpe_open(). A G_FMT before any S_FMTs will result in these values being
populated.

The colorspace and bytesperline parameter of this initial configuration are
incorrect. This breaks compliance when as we get 'TRY_FMT(G_FMT) != G_FMT'.

Fix the initial queue configuration such that it wouldn't need to be fixed by
try_fmt.

Reviewed-by: Hans Verkuil hans.verk...@cisco.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 3a312ea..d7befb9 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2021,9 +2021,11 @@ static int vpe_open(struct file *file)
s_q_data-fmt = vpe_formats[2];
s_q_data-width = 1920;
s_q_data-height = 1080;
-   s_q_data-sizeimage[VPE_LUMA] = (s_q_data-width * s_q_data-height *
+   s_q_data-bytesperline[VPE_LUMA] = (s_q_data-width *
s_q_data-fmt-vpdma_fmt[VPE_LUMA]-depth)  3;
-   s_q_data-colorspace = V4L2_COLORSPACE_SMPTE170M;
+   s_q_data-sizeimage[VPE_LUMA] = (s_q_data-bytesperline[VPE_LUMA] *
+   s_q_data-height);
+   s_q_data-colorspace = V4L2_COLORSPACE_REC709;
s_q_data-field = V4L2_FIELD_NONE;
s_q_data-c_rect.left = 0;
s_q_data-c_rect.top = 0;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 08/14] v4l: ti-vpe: Rename csc memory resource name

2014-03-13 Thread Archit Taneja
Rename the memory block resource vpe_csc to csc since it also exists within
the VIP IP block. This would make the name more generic, and both VPE and VIP DT
nodes in the future can use it.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/csc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/csc.c 
b/drivers/media/platform/ti-vpe/csc.c
index acfea50..039 100644
--- a/drivers/media/platform/ti-vpe/csc.c
+++ b/drivers/media/platform/ti-vpe/csc.c
@@ -180,7 +180,7 @@ struct csc_data *csc_create(struct platform_device *pdev)
csc-pdev = pdev;
 
csc-res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-   vpe_csc);
+   csc);
if (csc-res == NULL) {
dev_err(pdev-dev, missing platform resources data\n);
return ERR_PTR(-ENODEV);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 04/14] v4l: ti-vpe: Allow DMABUF buffer type support

2014-03-13 Thread Archit Taneja
For OMAP and DRA7x, we generally allocate video and graphics buffers through
omapdrm since the corresponding omap-gem driver provides DMM-Tiler backed
contiguous buffers. omapdrm is a dma-buf exporter. These buffers are used by
other drivers in the video pipeline.

Add VB2_DMABUF flag to the io_modes of the vb2 output and capture queues. This
allows the driver to import dma shared buffers.

Reviewed-by: Hans Verkuil hans.verk...@cisco.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 0363df6..0e7573a 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1770,7 +1770,7 @@ static int queue_init(void *priv, struct vb2_queue 
*src_vq,
 
memset(src_vq, 0, sizeof(*src_vq));
src_vq-type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-   src_vq-io_modes = VB2_MMAP;
+   src_vq-io_modes = VB2_MMAP | VB2_DMABUF;
src_vq-drv_priv = ctx;
src_vq-buf_struct_size = sizeof(struct v4l2_m2m_buffer);
src_vq-ops = vpe_qops;
@@ -1783,7 +1783,7 @@ static int queue_init(void *priv, struct vb2_queue 
*src_vq,
 
memset(dst_vq, 0, sizeof(*dst_vq));
dst_vq-type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   dst_vq-io_modes = VB2_MMAP;
+   dst_vq-io_modes = VB2_MMAP | VB2_DMABUF;
dst_vq-drv_priv = ctx;
dst_vq-buf_struct_size = sizeof(struct v4l2_m2m_buffer);
dst_vq-ops = vpe_qops;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 07/14] v4l: ti-vpe: Add selection API in VPE driver

2014-03-13 Thread Archit Taneja
Add selection ioctl ops. For VPE, cropping makes sense only for the input to
VPE(or V4L2_BUF_TYPE_VIDEO_OUTPUT/MPLANE buffers) and composing makes sense
only for the output of VPE(or V4L2_BUF_TYPE_VIDEO_CAPTURE/MPLANE buffers).

For the CAPTURE type, V4L2_SEL_TGT_COMPOSE results in VPE writing the output
in a rectangle within the capture buffer. For the OUTPUT type, V4L2_SEL_TGT_CROP
results in selecting a rectangle region within the source buffer.

Setting the crop/compose rectangles should successfully result in
re-configuration of registers which are affected when either source or
destination dimensions change, set_srcdst_params() is called for this purpose.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 150 
 1 file changed, 150 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index ece9b96..f3f1c10 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -410,8 +410,10 @@ static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx,
 {
switch (type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+   case V4L2_BUF_TYPE_VIDEO_OUTPUT:
return ctx-q_data[Q_DATA_SRC];
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+   case V4L2_BUF_TYPE_VIDEO_CAPTURE:
return ctx-q_data[Q_DATA_DST];
default:
BUG();
@@ -1587,6 +1589,151 @@ static int vpe_s_fmt(struct file *file, void *priv, 
struct v4l2_format *f)
return set_srcdst_params(ctx);
 }
 
+static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
+{
+   struct vpe_q_data *q_data;
+
+   if ((s-type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 
+   (s-type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
+   return -EINVAL;
+
+   q_data = get_q_data(ctx, s-type);
+   if (!q_data)
+   return -EINVAL;
+
+   switch (s-target) {
+   case V4L2_SEL_TGT_COMPOSE:
+   /*
+* COMPOSE target is only valid for capture buffer type, return
+* error for output buffer type
+*/
+   if (s-type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+   return -EINVAL;
+   break;
+   case V4L2_SEL_TGT_CROP:
+   /*
+* CROP target is only valid for output buffer type, return
+* error for capture buffer type
+*/
+   if (s-type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   return -EINVAL;
+   break;
+   /*
+* bound and default crop/compose targets are invalid targets to
+* try/set
+*/
+   default:
+   return -EINVAL;
+   }
+
+   if (s-r.top  0 || s-r.left  0) {
+   vpe_err(ctx-dev, negative values for top and left\n);
+   s-r.top = s-r.left = 0;
+   }
+
+   v4l_bound_align_image(s-r.width, MIN_W, q_data-width, 1,
+   s-r.height, MIN_H, q_data-height, H_ALIGN, S_ALIGN);
+
+   /* adjust left/top if cropping rectangle is out of bounds */
+   if (s-r.left + s-r.width  q_data-width)
+   s-r.left = q_data-width - s-r.width;
+   if (s-r.top + s-r.height  q_data-height)
+   s-r.top = q_data-height - s-r.height;
+
+   return 0;
+}
+
+static int vpe_g_selection(struct file *file, void *fh,
+   struct v4l2_selection *s)
+{
+   struct vpe_ctx *ctx = file2ctx(file);
+   struct vpe_q_data *q_data;
+   bool use_c_rect = false;
+
+   if ((s-type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 
+   (s-type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
+   return -EINVAL;
+
+   q_data = get_q_data(ctx, s-type);
+   if (!q_data)
+   return -EINVAL;
+
+   switch (s-target) {
+   case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+   case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+   if (s-type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+   return -EINVAL;
+   break;
+   case V4L2_SEL_TGT_CROP_BOUNDS:
+   case V4L2_SEL_TGT_CROP_DEFAULT:
+   if (s-type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   return -EINVAL;
+   break;
+   case V4L2_SEL_TGT_COMPOSE:
+   if (s-type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+   return -EINVAL;
+   use_c_rect = true;
+   break;
+   case V4L2_SEL_TGT_CROP:
+   if (s-type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   return -EINVAL;
+   use_c_rect = true;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   if (use_c_rect) {
+   /*
+* for CROP/COMPOSE target type, return c_rect params from the
+* respective buffer type
+*/
+   s-r = q_data-c_rect;
+   } else

[PATCH v4 01/14] v4l: ti-vpe: Make sure in job_ready that we have the needed number of dst_bufs

2014-03-13 Thread Archit Taneja
VPE has a ctrl parameter which decides how many mem to mem transactions the
active job from the job queue can perform.

The driver's job_ready() made sure that the number of ready source buffers are
sufficient for the job to execute successfully. But it didn't make sure if
there are sufficient ready destination buffers in the capture queue for the
VPE output.

If the time taken by VPE to process a single frame is really slow, then it's
possible that we don't need to imply such a restriction on the dst queue, but
really fast transactions(small resolution, no de-interlacing) may cause us to
hit the condition where we don't have any free buffers for the VPE to write on.

Add the extra check in job_ready() to make sure we have the sufficient amount
of destination buffers.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 7a77a5b..f3143ac 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -887,6 +887,9 @@ static int job_ready(void *priv)
if (v4l2_m2m_num_src_bufs_ready(ctx-m2m_ctx)  needed)
return 0;
 
+   if (v4l2_m2m_num_dst_bufs_ready(ctx-m2m_ctx)  needed)
+   return 0;
+
return 1;
 }
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 05/14] v4l: ti-vpe: Allow usage of smaller images

2014-03-13 Thread Archit Taneja
The minimum width and height for VPE input/output was kept as 128 pixels. VPE
doesn't have a constraint on the image height, it requires the image width to
be at least 16 bytes.

Change the minimum supported dimensions to 32x32. This allows us to de-interlace
qcif content. A smaller image size than 32x32 didn't make much sense, so stopped
at this.

Reviewed-by: Hans Verkuil hans.verk...@cisco.com
Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 0e7573a..dbdc338 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -49,8 +49,8 @@
 #define VPE_MODULE_NAME vpe
 
 /* minimum and maximum frame sizes */
-#define MIN_W  128
-#define MIN_H  128
+#define MIN_W  32
+#define MIN_H  32
 #define MAX_W  1920
 #define MAX_H  1080
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 02/14] v4l: ti-vpe: register video device only when firmware is loaded

2014-03-13 Thread Archit Taneja

Hi Kamil,

On Thursday 13 March 2014 05:18 PM, Kamil Debski wrote:

Hi Archit,


From: Archit Taneja [mailto:arc...@ti.com]
Sent: Tuesday, March 11, 2014 9:34 AM

vpe fops(vpe_open in particular) should be called only when VPDMA
firmware is loaded. File operations on the video device are possible
the moment it is registered.

Currently, we register the video device for VPE at driver probe, after
calling a vpdma helper to initialize VPDMA and load firmware. This
function is non-blocking(it calls request_firmware_nowait()), and
doesn't ensure that the firmware is actually loaded when it returns.

We remove the device registration from vpe probe, and move it to a
callback provided by the vpe driver to the vpdma library, through
vpdma_create().

The ready field in vpdma_data is no longer needed since we always have
firmware loaded before the device is registered.

A minor problem with this approach is that if the video_register_device
fails(which doesn't really happen), the vpe platform device would be
registered.
however, there won't be any v4l2 device corresponding to it.


Could you explain to me one thing. request_firmware cannot be used in
probe, thus you are using request_firmware_nowait. Why cannot the firmware
be
loaded on open with a regular request_firmware that is waiting?


I totally agree with you here. Placing the firmware in open() would 
probably make more sense.


The reason I didn't place it in open() is because I didn't want to 
release firmware in a corresponding close(), and be in a situation where 
the firmware is loaded multiple times in the driver's lifetime.


There are some reasons for doing this. First, it will require more 
testing with respect to whether the firmware is loaded correctly 
successive times :), the second is that loading firmware might probably 
take a bit of time, and we don't want to make applications too slow(I 
haven't measured the time taken, so I don't have a strong case for this 
either)




This patch seems to swap one problem for another. The possibility that open
fails (because firmware is not yet loaded) is swapped for a vague
possibility
that video_register_device.


The driver will work fine in most cases even without this patch(apart 
from the possibility mentioned as above).


We could discard this patch from this series, and I can work on a patch 
which moves firmware loading to the vpe_open() call, and hence solving 
the issue in the right manner. Does that sound fine?


Thanks,
Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 1/2] arm: dts: omap4+: Add DMM bindings

2014-03-11 Thread Archit Taneja

On Tuesday 11 March 2014 12:45 PM, Tomi Valkeinen wrote:

Hi,

On 15/10/13 10:04, Archit Taneja wrote:

Add Dynamic Memory Manager (DMM) bindings for OMAP4 and OMAP5 devices. DMM
only requires address and irq information.

Add documentation for the DMM bindings.

Originally worked on by Andy Gross andy...@gmail.com

Cc: Andy Gross andy...@gmail.com
Signed-off-by: Archit Taneja arc...@ti.com
---
  Documentation/devicetree/bindings/arm/omap/dmm.txt | 22 ++
  arch/arm/boot/dts/omap4.dtsi   |  7 +++
  arch/arm/boot/dts/omap5.dtsi   |  7 +++
  3 files changed, 36 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/arm/omap/dmm.txt


Has this been queued for 3.15?


Yes, It has got queued.

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 00/14] v4l: ti-vpe: Some VPE fixes and enhancements

2014-03-11 Thread Archit Taneja
This patch set mainly consists of minor fixes for the VPE driver. These fixes
ensure the following:

- The VPE module can be inserted and removed successively.
- Make sure that smaller resolutions like qcif work correctly.
- Prevent race condition between firmware loading and an open call to the v4l2
  device.
- Prevent the possibility of output m2m queue not having sufficient 'ready'
  buffers.
- Some VPDMA data descriptor fields weren't understood correctly before. They
  are now used correctly.

The rest of the patches add some minor features like DMA buf support and
cropping/composing.

Reference branch:

g...@github.com:boddob/linux.git vpe_for_315

Changes in v3:

- improvements in selection API patch.
- querycap fixes for v4l2 compliance.
- v4l2_buffer 'field' and flags' fixes for compliance.
- fixes in try_fmt vpe_open for compliance.
- rename a IOMEM resource for better DT compatibility.

Changes in v2:

- selection API used instead of older cropping API.
- Typo fix.
- Some changes in patch 6/7 to support composing on the capture side of VPE.


Archit Taneja (14):
  v4l: ti-vpe: Make sure in job_ready that we have the needed number of
dst_bufs
  v4l: ti-vpe: register video device only when firmware is loaded
  v4l: ti-vpe: Use video_device_release_empty
  v4l: ti-vpe: Allow DMABUF buffer type support
  v4l: ti-vpe: Allow usage of smaller images
  v4l: ti-vpe: Fix some params in VPE data descriptors
  v4l: ti-vpe: Add selection API in VPE driver
  v4l: ti-vpe: Rename csc memory resource name
  v4l: ti-vpe: report correct capabilities in querycap
  v4l: ti-vpe: Use correct bus_info name for the device in querycap
  v4l: ti-vpe: Fix initial configuration queue data
  v4l: ti-vpe: zero out reserved fields in try_fmt
  v4l: ti-vpe: Set correct field parameter for output and capture
buffers
  v4l: ti-vpe: retain v4l2_buffer flags for captured buffers

 drivers/media/platform/ti-vpe/csc.c   |   2 +-
 drivers/media/platform/ti-vpe/vpdma.c |  68 ++---
 drivers/media/platform/ti-vpe/vpdma.h |  17 ++-
 drivers/media/platform/ti-vpe/vpe.c   | 263 --
 4 files changed, 281 insertions(+), 69 deletions(-)

-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 01/14] v4l: ti-vpe: Make sure in job_ready that we have the needed number of dst_bufs

2014-03-11 Thread Archit Taneja
VPE has a ctrl parameter which decides how many mem to mem transactions the
active job from the job queue can perform.

The driver's job_ready() made sure that the number of ready source buffers are
sufficient for the job to execute successfully. But it didn't make sure if
there are sufficient ready destination buffers in the capture queue for the
VPE output.

If the time taken by VPE to process a single frame is really slow, then it's
possible that we don't need to imply such a restriction on the dst queue, but
really fast transactions(small resolution, no de-interlacing) may cause us to
hit the condition where we don't have any free buffers for the VPE to write on.

Add the extra check in job_ready() to make sure we have the sufficient amount
of destination buffers.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 7a77a5b..f3143ac 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -887,6 +887,9 @@ static int job_ready(void *priv)
if (v4l2_m2m_num_src_bufs_ready(ctx-m2m_ctx)  needed)
return 0;
 
+   if (v4l2_m2m_num_dst_bufs_ready(ctx-m2m_ctx)  needed)
+   return 0;
+
return 1;
 }
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 10/14] v4l: ti-vpe: Use correct bus_info name for the device in querycap

2014-03-11 Thread Archit Taneja
The bus_info parameter in v4l2_capabilities expects a 'platform_' prefix. This
wasn't done in the driver and hence was breaking compliance. Update the bus_info
parameter accordingly.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 46b9d44..5591d04 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1346,7 +1346,8 @@ static int vpe_querycap(struct file *file, void *priv,
 {
strncpy(cap-driver, VPE_MODULE_NAME, sizeof(cap-driver) - 1);
strncpy(cap-card, VPE_MODULE_NAME, sizeof(cap-card) - 1);
-   strlcpy(cap-bus_info, VPE_MODULE_NAME, sizeof(cap-bus_info));
+   snprintf(cap-bus_info, sizeof(cap-bus_info), platform:%s,
+   VPE_MODULE_NAME);
cap-device_caps  = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
cap-capabilities = cap-device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 05/14] v4l: ti-vpe: Allow usage of smaller images

2014-03-11 Thread Archit Taneja
The minimum width and height for VPE input/output was kept as 128 pixels. VPE
doesn't have a constraint on the image height, it requires the image width to
be at least 16 bytes.

Change the minimum supported dimensions to 32x32. This allows us to de-interlace
qcif content. A smaller image size than 32x32 didn't make much sense, so stopped
at this.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 0e7573a..dbdc338 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -49,8 +49,8 @@
 #define VPE_MODULE_NAME vpe
 
 /* minimum and maximum frame sizes */
-#define MIN_W  128
-#define MIN_H  128
+#define MIN_W  32
+#define MIN_H  32
 #define MAX_W  1920
 #define MAX_H  1080
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 02/14] v4l: ti-vpe: register video device only when firmware is loaded

2014-03-11 Thread Archit Taneja
vpe fops(vpe_open in particular) should be called only when VPDMA firmware
is loaded. File operations on the video device are possible the moment it is
registered.

Currently, we register the video device for VPE at driver probe, after calling
a vpdma helper to initialize VPDMA and load firmware. This function is
non-blocking(it calls request_firmware_nowait()), and doesn't ensure that the
firmware is actually loaded when it returns.

We remove the device registration from vpe probe, and move it to a callback
provided by the vpe driver to the vpdma library, through vpdma_create().

The ready field in vpdma_data is no longer needed since we always have firmware
loaded before the device is registered.

A minor problem with this approach is that if the video_register_device
fails(which doesn't really happen), the vpe platform device would be registered.
however, there won't be any v4l2 device corresponding to it.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpdma.c |  8 +++--
 drivers/media/platform/ti-vpe/vpdma.h |  7 +++--
 drivers/media/platform/ti-vpe/vpe.c   | 55 ---
 3 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c 
b/drivers/media/platform/ti-vpe/vpdma.c
index e8175e7..73dd38e 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -781,7 +781,7 @@ static void vpdma_firmware_cb(const struct firmware *f, 
void *context)
/* already initialized */
if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
VPDMA_LIST_RDY_SHFT)) {
-   vpdma-ready = true;
+   vpdma-cb(vpdma-pdev);
return;
}
 
@@ -811,7 +811,7 @@ static void vpdma_firmware_cb(const struct firmware *f, 
void *context)
goto free_buf;
}
 
-   vpdma-ready = true;
+   vpdma-cb(vpdma-pdev);
 
 free_buf:
vpdma_unmap_desc_buf(vpdma, fw_dma_buf);
@@ -839,7 +839,8 @@ static int vpdma_load_firmware(struct vpdma_data *vpdma)
return 0;
 }
 
-struct vpdma_data *vpdma_create(struct platform_device *pdev)
+struct vpdma_data *vpdma_create(struct platform_device *pdev,
+   void (*cb)(struct platform_device *pdev))
 {
struct resource *res;
struct vpdma_data *vpdma;
@@ -854,6 +855,7 @@ struct vpdma_data *vpdma_create(struct platform_device 
*pdev)
}
 
vpdma-pdev = pdev;
+   vpdma-cb = cb;
 
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, vpdma);
if (res == NULL) {
diff --git a/drivers/media/platform/ti-vpe/vpdma.h 
b/drivers/media/platform/ti-vpe/vpdma.h
index cf40f11..bf5f8bb 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -35,8 +35,8 @@ struct vpdma_data {
 
struct platform_device  *pdev;
 
-   /* tells whether vpdma firmware is loaded or not */
-   bool ready;
+   /* callback to VPE driver when the firmware is loaded */
+   void (*cb)(struct platform_device *pdev);
 };
 
 enum vpdma_data_format_type {
@@ -208,6 +208,7 @@ void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
 void vpdma_dump_regs(struct vpdma_data *vpdma);
 
 /* initialize vpdma, passed with VPE's platform device pointer */
-struct vpdma_data *vpdma_create(struct platform_device *pdev);
+struct vpdma_data *vpdma_create(struct platform_device *pdev,
+   void (*cb)(struct platform_device *pdev));
 
 #endif
diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index f3143ac..f1eae67 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1817,11 +1817,6 @@ static int vpe_open(struct file *file)
 
vpe_dbg(dev, vpe_open\n);
 
-   if (!dev-vpdma-ready) {
-   vpe_err(dev, vpdma firmware not loaded\n);
-   return -ENODEV;
-   }
-
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
@@ -2039,10 +2034,40 @@ static void vpe_runtime_put(struct platform_device 
*pdev)
WARN_ON(r  0  r != -ENOSYS);
 }
 
+static void vpe_fw_cb(struct platform_device *pdev)
+{
+   struct vpe_dev *dev = platform_get_drvdata(pdev);
+   struct video_device *vfd;
+   int ret;
+
+   vfd = dev-vfd;
+   *vfd = vpe_videodev;
+   vfd-lock = dev-dev_mutex;
+   vfd-v4l2_dev = dev-v4l2_dev;
+
+   ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+   if (ret) {
+   vpe_err(dev, Failed to register video device\n);
+
+   vpe_set_clock_enable(dev, 0);
+   vpe_runtime_put(pdev);
+   pm_runtime_disable(pdev-dev);
+   v4l2_m2m_release(dev-m2m_dev);
+   vb2_dma_contig_cleanup_ctx(dev-alloc_ctx);
+   v4l2_device_unregister(dev-v4l2_dev);
+
+   return;
+   }
+
+   video_set_drvdata

[PATCH v3 12/14] v4l: ti-vpe: zero out reserved fields in try_fmt

2014-03-11 Thread Archit Taneja
Zero out the reserved formats in v4l2_pix_format_mplane and
v4l2_plane_pix_format members of the returned v4l2_format pointer when passed
through TRY_FMT ioctl.

This ensures that the user doesn't interpret the non-zero fields as some data
passed by the driver, and ensures compliance.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 85d1122..970408a 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1488,6 +1488,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct 
v4l2_format *f,
}
}
 
+   memset(pix-reserved, 0, sizeof(pix-reserved));
for (i = 0; i  pix-num_planes; i++) {
plane_fmt = pix-plane_fmt[i];
depth = fmt-vpdma_fmt[i]-depth;
@@ -1499,6 +1500,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct 
v4l2_format *f,
 
plane_fmt-sizeimage =
(pix-height * pix-width * depth)  3;
+
+   memset(plane_fmt-reserved, 0, sizeof(plane_fmt-reserved));
}
 
return 0;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 13/14] v4l: ti-vpe: Set correct field parameter for output and capture buffers

2014-03-11 Thread Archit Taneja
The vpe driver wasn't setting the correct field parameter for dequed CAPTURE
type buffers for the case where the captured output is progressive.

Set the field to V4L2_FIELD_NONE for the completed destination buffers when
the captured output is progressive.

For OUTPUT type buffers, a queued buffer's field is forced to V4L2_FIELD_NONE
if the pixel format(configured through s_fmt for the buffer type
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE specifies) the field type isn't interlaced.
If the pixel format specified was V4L2_FIELD_ALTERNATE, and the queued buffer's
field isn't V4L2_FIELD_TOP or V4L2_FIELD_BOTTOM, the vb2 buf_prepare op returns
an error.

This ensures compliance, and that the dequeued output and captured buffers
contain the field type that the driver used internally.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 970408a..c884910 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1296,10 +1296,10 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
d_buf-timecode = s_buf-timecode;
}
d_buf-sequence = ctx-sequence;
-   d_buf-field = ctx-field;
 
d_q_data = ctx-q_data[Q_DATA_DST];
if (d_q_data-flags  Q_DATA_INTERLACED) {
+   d_buf-field = ctx-field;
if (ctx-field == V4L2_FIELD_BOTTOM) {
ctx-sequence++;
ctx-field = V4L2_FIELD_TOP;
@@ -1308,6 +1308,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
ctx-field = V4L2_FIELD_BOTTOM;
}
} else {
+   d_buf-field = V4L2_FIELD_NONE;
ctx-sequence++;
}
 
@@ -1871,6 +1872,16 @@ static int vpe_buf_prepare(struct vb2_buffer *vb)
q_data = get_q_data(ctx, vb-vb2_queue-type);
num_planes = q_data-fmt-coplanar ? 2 : 1;
 
+   if (vb-vb2_queue-type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+   if (!(q_data-flags  Q_DATA_INTERLACED)) {
+   vb-v4l2_buf.field = V4L2_FIELD_NONE;
+   } else {
+   if (vb-v4l2_buf.field != V4L2_FIELD_TOP ||
+   vb-v4l2_buf.field != V4L2_FIELD_BOTTOM)
+   return -EINVAL;
+   }
+   }
+
for (i = 0; i  num_planes; i++) {
if (vb2_plane_size(vb, i)  q_data-sizeimage[i]) {
vpe_err(ctx-dev,
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 14/14] v4l: ti-vpe: retain v4l2_buffer flags for captured buffers

2014-03-11 Thread Archit Taneja
The dequed CAPTURE_MPLANE type buffers don't contain the flags that the
originally queued OUTPUT_MPLANE type buffers have. This breaks compliance.

Copy the source v4l2_buffer flags to the destination v4l2_buffer flags before
they are dequed.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index c884910..f7759e8 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1288,13 +1288,12 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
s_buf = s_vb-v4l2_buf;
d_buf = d_vb-v4l2_buf;
 
+   d_buf-flags = s_buf-flags;
+
d_buf-timestamp = s_buf-timestamp;
-   d_buf-flags = ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
-   d_buf-flags |= s_buf-flags  V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
-   if (s_buf-flags  V4L2_BUF_FLAG_TIMECODE) {
-   d_buf-flags |= V4L2_BUF_FLAG_TIMECODE;
+   if (s_buf-flags  V4L2_BUF_FLAG_TIMECODE)
d_buf-timecode = s_buf-timecode;
-   }
+
d_buf-sequence = ctx-sequence;
 
d_q_data = ctx-q_data[Q_DATA_DST];
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 11/14] v4l: ti-vpe: Fix initial configuration queue data

2014-03-11 Thread Archit Taneja
The vpe output and capture queues are initially configured to default values in
vpe_open(). A G_FMT before any S_FMTs will result in these values being
populated.

The colorspace and bytesperline parameter of this initial configuration are
incorrect. This breaks compliance when as we get 'TRY_FMT(G_FMT) != G_FMT'.

Fix the initial queue configuration such that it wouldn't need to be fixed by
try_fmt.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 5591d04..85d1122 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2012,9 +2012,11 @@ static int vpe_open(struct file *file)
s_q_data-fmt = vpe_formats[2];
s_q_data-width = 1920;
s_q_data-height = 1080;
-   s_q_data-sizeimage[VPE_LUMA] = (s_q_data-width * s_q_data-height *
+   s_q_data-bytesperline[VPE_LUMA] = (s_q_data-width *
s_q_data-fmt-vpdma_fmt[VPE_LUMA]-depth)  3;
-   s_q_data-colorspace = V4L2_COLORSPACE_SMPTE170M;
+   s_q_data-sizeimage[VPE_LUMA] = (s_q_data-bytesperline[VPE_LUMA] *
+   s_q_data-height);
+   s_q_data-colorspace = V4L2_COLORSPACE_REC709;
s_q_data-field = V4L2_FIELD_NONE;
s_q_data-c_rect.left = 0;
s_q_data-c_rect.top = 0;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 09/14] v4l: ti-vpe: report correct capabilities in querycap

2014-03-11 Thread Archit Taneja
querycap currently returns V4L2_CAP_VIDEO_M2M as a capability, this should be
V4L2_CAP_VIDEO_M2M_MPLANE instead, as the driver supports multiplanar formats.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 4abb85c..46b9d44 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1347,7 +1347,7 @@ static int vpe_querycap(struct file *file, void *priv,
strncpy(cap-driver, VPE_MODULE_NAME, sizeof(cap-driver) - 1);
strncpy(cap-card, VPE_MODULE_NAME, sizeof(cap-card) - 1);
strlcpy(cap-bus_info, VPE_MODULE_NAME, sizeof(cap-bus_info));
-   cap-device_caps  = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
+   cap-device_caps  = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
cap-capabilities = cap-device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 07/14] v4l: ti-vpe: Add selection API in VPE driver

2014-03-11 Thread Archit Taneja
Add selection ioctl ops. For VPE, cropping makes sense only for the input to
VPE(or V4L2_BUF_TYPE_VIDEO_OUTPUT/MPLANE buffers) and composing makes sense
only for the output of VPE(or V4L2_BUF_TYPE_VIDEO_CAPTURE/MPLANE buffers).

For the CAPTURE type, V4L2_SEL_TGT_COMPOSE results in VPE writing the output
in a rectangle within the capture buffer. For the OUTPUT type, V4L2_SEL_TGT_CROP
results in selecting a rectangle region within the source buffer.

Setting the crop/compose rectangles should successfully result in
re-configuration of registers which are affected when either source or
destination dimensions change, set_srcdst_params() is called for this purpose.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 141 
 1 file changed, 141 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index ece9b96..4abb85c 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -410,8 +410,10 @@ static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx,
 {
switch (type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+   case V4L2_BUF_TYPE_VIDEO_OUTPUT:
return ctx-q_data[Q_DATA_SRC];
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+   case V4L2_BUF_TYPE_VIDEO_CAPTURE:
return ctx-q_data[Q_DATA_DST];
default:
BUG();
@@ -1587,6 +1589,142 @@ static int vpe_s_fmt(struct file *file, void *priv, 
struct v4l2_format *f)
return set_srcdst_params(ctx);
 }
 
+static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
+{
+   struct vpe_q_data *q_data;
+
+   if ((s-type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 
+   (s-type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
+   return -EINVAL;
+
+   q_data = get_q_data(ctx, s-type);
+   if (!q_data)
+   return -EINVAL;
+
+   switch (s-target) {
+   case V4L2_SEL_TGT_COMPOSE:
+   /*
+* COMPOSE target is only valid for capture buffer type, for
+* output buffer type, assign existing crop parameters to the
+* selection rectangle
+*/
+   if (s-type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   break;
+
+   s-r = q_data-c_rect;
+   return 0;
+
+   case V4L2_SEL_TGT_CROP:
+   /*
+* CROP target is only valid for output buffer type, for capture
+* buffer type, assign existing compose parameters to the
+* selection rectangle
+*/
+   if (s-type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+   break;
+
+   s-r = q_data-c_rect;
+   return 0;
+
+   /*
+* bound and default crop/compose targets are invalid targets to
+* try/set
+*/
+   default:
+   return -EINVAL;
+   }
+
+   if (s-r.top  0 || s-r.left  0) {
+   vpe_err(ctx-dev, negative values for top and left\n);
+   s-r.top = s-r.left = 0;
+   }
+
+   v4l_bound_align_image(s-r.width, MIN_W, q_data-width, 1,
+   s-r.height, MIN_H, q_data-height, H_ALIGN, S_ALIGN);
+
+   /* adjust left/top if cropping rectangle is out of bounds */
+   if (s-r.left + s-r.width  q_data-width)
+   s-r.left = q_data-width - s-r.width;
+   if (s-r.top + s-r.height  q_data-height)
+   s-r.top = q_data-height - s-r.height;
+
+   return 0;
+}
+
+static int vpe_g_selection(struct file *file, void *fh,
+   struct v4l2_selection *s)
+{
+   struct vpe_ctx *ctx = file2ctx(file);
+   struct vpe_q_data *q_data;
+
+   if ((s-type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 
+   (s-type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
+   return -EINVAL;
+
+   q_data = get_q_data(ctx, s-type);
+   if (!q_data)
+   return -EINVAL;
+
+   switch (s-target) {
+   /* return width and height from S_FMT of the respective buffer type */
+   case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+   case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+   case V4L2_SEL_TGT_CROP_BOUNDS:
+   case V4L2_SEL_TGT_CROP_DEFAULT:
+   s-r.left = 0;
+   s-r.top = 0;
+   s-r.width = q_data-width;
+   s-r.height = q_data-height;
+   return 0;
+
+   /*
+* CROP target holds for the output buffer type, and COMPOSE target
+* holds for the capture buffer type. We still return the c_rect params
+* for both the target types.
+*/
+   case V4L2_SEL_TGT_COMPOSE:
+   case V4L2_SEL_TGT_CROP:
+   s-r.left = q_data-c_rect.left;
+   s-r.top = q_data-c_rect.top;
+   s-r.width = q_data-c_rect.width;
+   s-r.height = q_data-c_rect.height;
+   return 0;
+   }
+
+   return

[PATCH v3 08/14] v4l: ti-vpe: Rename csc memory resource name

2014-03-11 Thread Archit Taneja
Rename the memory block resource vpe_csc to csc since it also exists within
the VIP IP block. This would make the name more generic, and both VPE and VIP DT
nodes in the future can use it.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/csc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/csc.c 
b/drivers/media/platform/ti-vpe/csc.c
index acfea50..039 100644
--- a/drivers/media/platform/ti-vpe/csc.c
+++ b/drivers/media/platform/ti-vpe/csc.c
@@ -180,7 +180,7 @@ struct csc_data *csc_create(struct platform_device *pdev)
csc-pdev = pdev;
 
csc-res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-   vpe_csc);
+   csc);
if (csc-res == NULL) {
dev_err(pdev-dev, missing platform resources data\n);
return ERR_PTR(-ENODEV);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 03/14] v4l: ti-vpe: Use video_device_release_empty

2014-03-11 Thread Archit Taneja
The video_device struct is currently embedded in the driver data struct vpe_dev.
A vpe_dev instance is allocated by the driver, and the memory for the vfd is a
part of this struct.

The v4l2 core, however, manages the removal of the vfd region, through the
video_device's .release() op, which currently is the helper
video_device_release. This causes memory corruption, and leads to issues when
we try to re-insert the vpe module.

Use the video_device_release_empty helper function instead

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index f1eae67..0363df6 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2000,7 +2000,7 @@ static struct video_device vpe_videodev = {
.fops   = vpe_fops,
.ioctl_ops  = vpe_ioctl_ops,
.minor  = -1,
-   .release= video_device_release,
+   .release= video_device_release_empty,
.vfl_dir= VFL_DIR_M2M,
 };
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 06/14] v4l: ti-vpe: Fix some params in VPE data descriptors

2014-03-11 Thread Archit Taneja
Some parameters of the VPE descriptors were understood incorrectly. They are now
fixed. The fixes are explained as follows:

- When adding an inbound data descriptor to the VPDMA descriptor list, we intend
  to use c_rect as the cropped region fetched by VPDMA. Therefore, c_rect-width
  shouldn't be used to calculate the line stride, the original image width
  should be used for that. We add a 'width' argument which gives the buffer
  width in memory.

- frame_width and frame_height describe the complete width and height of the
  client to which the channel is connected. If there are multiple channels
  fetching data and providing to the same client, the above 2 arguments should
  be the width and height of the region covered by all the channels. In the case
  where there is only one channel providing pixel data to the client
  (like in VPE), frame_width and frame_height should be the cropped width and
  cropped height respectively. The calculation of these params is done in the
  vpe driver now.

- start_h and start_v is also used in the case of multiple channels to describe
  where each channel should start filling pixel data. We don't use this in VPE,
  and pass 0s to the vpdma_add_in_dtd() helper.

- Some minor changes are made to the vpdma_add_out_dtd() helper. The c_rect
  param is used for specifying the 'composition' target, and 'width'  is added
  to calculate the line stride.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpdma.c | 60 +++
 drivers/media/platform/ti-vpe/vpdma.h | 10 +++---
 drivers/media/platform/ti-vpe/vpe.c   | 18 +++
 3 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c 
b/drivers/media/platform/ti-vpe/vpdma.c
index 73dd38e..a51a013 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -614,8 +614,17 @@ static void dump_dtd(struct vpdma_dtd *dtd)
 /*
  * append an outbound data transfer descriptor to the given descriptor list,
  * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel
+ *
+ * @list: vpdma desc list to which we add this decriptor
+ * @width: width of the image in pixels in memory
+ * @c_rect: compose params of output image
+ * @fmt: vpdma data format of the buffer
+ * dma_addr: dma address as seen by VPDMA
+ * chan: VPDMA channel
+ * flags: VPDMA flags to configure some descriptor fileds
  */
-void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
+void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
+   const struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
enum vpdma_channel chan, u32 flags)
 {
@@ -623,6 +632,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct 
v4l2_rect *c_rect,
int field = 0;
int notify = 1;
int channel, next_chan;
+   struct v4l2_rect rect = *c_rect;
int depth = fmt-depth;
int stride;
struct vpdma_dtd *dtd;
@@ -630,11 +640,15 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, 
struct v4l2_rect *c_rect,
channel = next_chan = chan_info[chan].num;
 
if (fmt-type == VPDMA_DATA_FMT_TYPE_YUV 
-   fmt-data_type == DATA_TYPE_C420)
+   fmt-data_type == DATA_TYPE_C420) {
+   rect.height = 1;
+   rect.top = 1;
depth = 8;
+   }
 
-   stride = ALIGN((depth * c_rect-width)  3, VPDMA_STRIDE_ALIGN);
-   dma_addr += (c_rect-left * depth)  3;
+   stride = ALIGN((depth * width)  3, VPDMA_STRIDE_ALIGN);
+
+   dma_addr += rect.top * stride + (rect.left * depth  3);
 
dtd = list-next;
WARN_ON((void *)(dtd + 1)  (list-buf.addr + list-buf.size));
@@ -664,31 +678,48 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, 
struct v4l2_rect *c_rect,
 /*
  * append an inbound data transfer descriptor to the given descriptor list,
  * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel
+ *
+ * @list: vpdma desc list to which we add this decriptor
+ * @width: width of the image in pixels in memory(not the cropped width)
+ * @c_rect: crop params of input image
+ * @fmt: vpdma data format of the buffer
+ * dma_addr: dma address as seen by VPDMA
+ * chan: VPDMA channel
+ * field: top or bottom field info of the input image
+ * flags: VPDMA flags to configure some descriptor fileds
+ * frame_width/height: the complete width/height of the image presented to the
+ * client (this makes sense when multiple channels are
+ * connected to the same client, forming a larger frame)
+ * start_h, start_v: position where the given channel starts providing pixel
+ * data to the client (makes sense when multiple channels
+ * contribute to the client)
  */
-void vpdma_add_in_dtd(struct

[PATCH v3 04/14] v4l: ti-vpe: Allow DMABUF buffer type support

2014-03-11 Thread Archit Taneja
For OMAP and DRA7x, we generally allocate video and graphics buffers through
omapdrm since the corresponding omap-gem driver provides DMM-Tiler backed
contiguous buffers. omapdrm is a dma-buf exporter. These buffers are used by
other drivers in the video pipeline.

Add VB2_DMABUF flag to the io_modes of the vb2 output and capture queues. This
allows the driver to import dma shared buffers.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 0363df6..0e7573a 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1770,7 +1770,7 @@ static int queue_init(void *priv, struct vb2_queue 
*src_vq,
 
memset(src_vq, 0, sizeof(*src_vq));
src_vq-type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-   src_vq-io_modes = VB2_MMAP;
+   src_vq-io_modes = VB2_MMAP | VB2_DMABUF;
src_vq-drv_priv = ctx;
src_vq-buf_struct_size = sizeof(struct v4l2_m2m_buffer);
src_vq-ops = vpe_qops;
@@ -1783,7 +1783,7 @@ static int queue_init(void *priv, struct vb2_queue 
*src_vq,
 
memset(dst_vq, 0, sizeof(*dst_vq));
dst_vq-type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   dst_vq-io_modes = VB2_MMAP;
+   dst_vq-io_modes = VB2_MMAP | VB2_DMABUF;
dst_vq-drv_priv = ctx;
dst_vq-buf_struct_size = sizeof(struct v4l2_m2m_buffer);
dst_vq-ops = vpe_qops;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 07/14] v4l: ti-vpe: Add selection API in VPE driver

2014-03-11 Thread Archit Taneja

On Tuesday 11 March 2014 05:51 PM, Hans Verkuil wrote:

Hi Archit,

A few small comments below...

On 03/11/14 09:33, Archit Taneja wrote:

Add selection ioctl ops. For VPE, cropping makes sense only for the input to
VPE(or V4L2_BUF_TYPE_VIDEO_OUTPUT/MPLANE buffers) and composing makes sense
only for the output of VPE(or V4L2_BUF_TYPE_VIDEO_CAPTURE/MPLANE buffers).

For the CAPTURE type, V4L2_SEL_TGT_COMPOSE results in VPE writing the output
in a rectangle within the capture buffer. For the OUTPUT type, V4L2_SEL_TGT_CROP
results in selecting a rectangle region within the source buffer.

Setting the crop/compose rectangles should successfully result in
re-configuration of registers which are affected when either source or
destination dimensions change, set_srcdst_params() is called for this purpose.

Signed-off-by: Archit Taneja arc...@ti.com
---
  drivers/media/platform/ti-vpe/vpe.c | 141 
  1 file changed, 141 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index ece9b96..4abb85c 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -410,8 +410,10 @@ static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx,
  {
switch (type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+   case V4L2_BUF_TYPE_VIDEO_OUTPUT:
return ctx-q_data[Q_DATA_SRC];
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+   case V4L2_BUF_TYPE_VIDEO_CAPTURE:
return ctx-q_data[Q_DATA_DST];
default:
BUG();
@@ -1587,6 +1589,142 @@ static int vpe_s_fmt(struct file *file, void *priv, 
struct v4l2_format *f)
return set_srcdst_params(ctx);
  }

+static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
+{
+   struct vpe_q_data *q_data;
+
+   if ((s-type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 
+   (s-type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
+   return -EINVAL;
+
+   q_data = get_q_data(ctx, s-type);
+   if (!q_data)
+   return -EINVAL;
+
+   switch (s-target) {
+   case V4L2_SEL_TGT_COMPOSE:
+   /*
+* COMPOSE target is only valid for capture buffer type, for
+* output buffer type, assign existing crop parameters to the
+* selection rectangle
+*/
+   if (s-type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   break;


Shouldn't this return -EINVAL?


compose only makes sense for CAPTURE. So, it breaks and performs the 
calculations after the switch statement.





+
+   s-r = q_data-c_rect;
+   return 0;


The above 2 lines are called for if we try to set compose for OUTPUT. I 
don't return an error here, just keep the size as the original rect 
size, and return 0.


I'll replace these 2 lines with 'return -EINVAL;'


+
+   case V4L2_SEL_TGT_CROP:
+   /*
+* CROP target is only valid for output buffer type, for capture
+* buffer type, assign existing compose parameters to the
+* selection rectangle
+*/
+   if (s-type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+   break;


Ditto.


+
+   s-r = q_data-c_rect;
+   return 0;
+
+   /*
+* bound and default crop/compose targets are invalid targets to
+* try/set
+*/
+   default:
+   return -EINVAL;
+   }
+
+   if (s-r.top  0 || s-r.left  0) {
+   vpe_err(ctx-dev, negative values for top and left\n);
+   s-r.top = s-r.left = 0;
+   }
+
+   v4l_bound_align_image(s-r.width, MIN_W, q_data-width, 1,
+   s-r.height, MIN_H, q_data-height, H_ALIGN, S_ALIGN);
+
+   /* adjust left/top if cropping rectangle is out of bounds */
+   if (s-r.left + s-r.width  q_data-width)
+   s-r.left = q_data-width - s-r.width;
+   if (s-r.top + s-r.height  q_data-height)
+   s-r.top = q_data-height - s-r.height;
+
+   return 0;
+}
+
+static int vpe_g_selection(struct file *file, void *fh,
+   struct v4l2_selection *s)
+{
+   struct vpe_ctx *ctx = file2ctx(file);
+   struct vpe_q_data *q_data;
+
+   if ((s-type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 
+   (s-type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
+   return -EINVAL;
+
+   q_data = get_q_data(ctx, s-type);
+   if (!q_data)
+   return -EINVAL;
+
+   switch (s-target) {
+   /* return width and height from S_FMT of the respective buffer type */
+   case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+   case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+   case V4L2_SEL_TGT_CROP_BOUNDS:
+   case V4L2_SEL_TGT_CROP_DEFAULT:
+   s-r.left = 0;
+   s-r.top = 0;
+   s-r.width = q_data-width;
+   s-r.height = q_data-height;


The crop targets only make sense

Re: [PATCH v3 07/14] v4l: ti-vpe: Add selection API in VPE driver

2014-03-11 Thread Archit Taneja

On Tuesday 11 March 2014 06:19 PM, Hans Verkuil wrote:

On 03/11/14 13:46, Archit Taneja wrote:

On Tuesday 11 March 2014 05:51 PM, Hans Verkuil wrote:

Hi Archit,

A few small comments below...

On 03/11/14 09:33, Archit Taneja wrote:


snip


Yes. If for no other reason that I plan on adding crop/compose/scaling support
to v4l2-compliance soon, and this will probably be one of the tests.


Thanks, will update. Thanks for reviewing of the series.

Archit





Thanks,
Archit

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html




--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 7/7] v4l: ti-vpe: Add selection API in VPE driver

2014-03-10 Thread Archit Taneja

Hi Hans,

On Friday 07 March 2014 07:17 PM, Archit Taneja wrote:

On Friday 07 March 2014 07:02 PM, Hans Verkuil wrote:

On 03/07/2014 02:22 PM, Archit Taneja wrote:




Disregard what I said, it's OK to upstream it. But if you could just
spend
some hours fixing the problems, that would really be best.


Sure, I'll try to fix these issues and then post a v3.


I fixed most of the compliance errors. There were some things I needed 
to change in .utils/v4l2-compliance/v4l2-test-buffers.cpp'. I added 
those with some questions in the comments:


diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp 
b/utils/v4l2-compliance/v4l2-test-buffers.cpp

index 6576d11..532a5b6 100644
--- a/utils/v4l2-compliance/v4l2-test-buffers.cpp
+++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp
@@ -219,7 +219,13 @@ static int checkQueryBuf(struct node *node, const 
struct v4l2_buffer buf,

fail_on_test(!(buf.flags  (V4L2_BUF_FLAG_DONE | 
V4L2_BUF_FLAG_ERROR)));
if (node-is_video) {
fail_on_test(buf.field == V4L2_FIELD_ALTERNATE);
-   fail_on_test(buf.field == V4L2_FIELD_ANY);
+   /*
+* the OUTPUT buffers are queued with V4L2_FIELD_ANY
+* field type by the application. Is it the driver's
+* job to change this to NONE in buf_prepare?
+*/
+
+   /* fail_on_test(buf.field == V4L2_FIELD_ANY); */
if (cur_fmt.fmt.pix.field == V4L2_FIELD_ALTERNATE) {
fail_on_test(buf.field != V4L2_FIELD_BOTTOM 
buf.field != V4L2_FIELD_TOP);
@@ -651,9 +657,17 @@ static int captureBufs(struct node *node, const 
struct v4l2_requestbuffers bufs

} else if (node-is_m2m  timestamp == 
V4L2_BUF_FLAG_TIMESTAMP_COPY) {
fail_on_test(buffer_info.find(buf.timestamp) == 
buffer_info.end());
struct v4l2_buffer orig_buf = 
buffer_info[buf.timestamp];
-   fail_on_test(buf.field != orig_buf.field);
-   fail_on_test((buf.flags  valid_output_flags) !=
-(orig_buf.flags  
valid_output_flags));
+   /* same issue as as in checkQueryBuf */
+   /* fail_on_test(buf.field != orig_buf.field); */
+
+   /*
+* the queued buffers are filled with flags like
+* V4L2_BUF_FLAG_KEYFRAME, these are lost when
+* the captured buffers are dequed. How do we
+* fix this?
+*/
+   /*fail_on_test((buf.flags  valid_output_flags) 
!=
+(orig_buf.flags  
valid_output_flags)); */
if (buf.flags  V4L2_BUF_FLAG_TIMECODE)
fail_on_test(memcmp(buf.timecode, 
orig_buf.timecode,

sizeof(buf.timecode)));


Thanks,
Archit
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 7/7] v4l: ti-vpe: Add selection API in VPE driver

2014-03-07 Thread Archit Taneja

Hi Hans,

On Tuesday 04 March 2014 05:05 PM, Hans Verkuil wrote:

On 03/04/14 12:25, Archit Taneja wrote:

I had a minor question about the selection API:

Are the V4L2_SET_TGT_CROP/COMPOSE_DEFAULT and the corresponding
'BOUNDS' targets supposed to be used with VIDIOC_S_SELECTION? If so,
what's the expect behaviour?


No, those are read only in practice. So only used with G_SELECTION, never
with S_SELECTION.


snip

I tried the v4l2-compliance thing. It's awesome! And a bit annoying too 
when it comes to fixing little things needed for compliance :). But it's 
required, and I hope to fix these eventually.


After a few small fixes in the driver, I get the results as below. I am 
debugging the cause of try_fmt and s_fmt failures. I'm not sure why the 
streaming test fails with MMAP, the logs of my driver show that a 
successful mem2mem transaction happened.


I tried this on the 'vb2-part1' branch as you suggested.

Do you think I can go ahead with posting the v3 patch set for 3.15, and 
work on fixing the compliance issue for the -rc fixes?


Thanks,
Archit

# ./utils/v4l2-compliance/v4l2-compliance  -v --streaming=10
root@localhost:~/source_trees/v4l-utils# Driver Info:
Driver name   : vpe
Card type : vpe
Bus info  : platform:vpe
Driver version: 3.14.0
Capabilities  : 0x84004000
Video Memory-to-Memory Multiplanar
Streaming
Device Capabilities
Device Caps   : 0x04004000
Video Memory-to-Memory Multiplanar
Streaming

Compliance test for device /dev/video0 (not using libv4l2):

Required ioctls:
test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
test second video open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK

Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Control ioctls:
info: checking v4l2_queryctrl of control 'User 
Controls' (0x00980001)
info: checking v4l2_queryctrl of control 'Buffers Per 
Transaction' (0x00981950)
info: checking v4l2_queryctrl of control 'Buffers Per 
Transaction' (0x0800)

test VIDIOC_QUERYCTRL/MENU: OK
info: checking control 'User Controls' (0x00980001)
info: checking control 'Buffers Per Transaction' 
(0x00981950)

test VIDIOC_G/S_CTRL: OK
info: checking extended control 'User Controls' 
(0x00980001)
info: checking extended control 'Buffers Per 
Transaction' (0x00981950)

test VIDIOC_G/S/TRY_EXT_CTRLS: OK
info: checking control event 'User Controls' (0x00980001)
info: checking control event 'Buffers Per Transaction' 
(0x00981950)

test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 1 Private Controls: 1

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)

Format ioctls:
info: found 8 formats for buftype 9
info: found 4 formats for buftype 10
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
fail: v4l2-test-formats.cpp(614): Video Capture 
Multiplanar: TRY_FMT(G_FMT) != G_FMT

test VIDIOC_TRY_FMT: FAIL
warn: v4l2-test-formats.cpp(834): S_FMT cannot handle 
an invalid pixelformat.
warn: v4l2-test-formats.cpp(835): This may or may not 
be a problem. For more information see:
warn: v4l2-test-formats.cpp(836): 
http://www.mail-archive.com/linux-media@vger.kernel.org/msg56550.html
fail: v4l2-test-formats.cpp(420): pix_mp.reserved not 
zeroed
fail: v4l2-test-formats.cpp(851): Video Capture 
Multiplanar is valid, but no S_FMT was implemented

test VIDIOC_S_FMT: FAIL
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)

Codec ioctls:
test VIDIOC_(TRY_

Re: [PATCH v2 7/7] v4l: ti-vpe: Add selection API in VPE driver

2014-03-07 Thread Archit Taneja

Hi,

On Friday 07 March 2014 06:29 PM, Hans Verkuil wrote:


Do you think I can go ahead with posting the v3 patch set for 3.15, and
work on fixing the compliance issue for the -rc fixes?


It's fine to upstream this in staging, but while not all compliance errors
are fixed it can't go to drivers/media. I'm tightening the screws on that
since v4l2-compliance is getting to be such a powerful tool for ensuring
the driver complies.



But the vpe driver is already in drivers/media. How do I push these 
patches if the vpe drivers is not in staging?


snip


Multiplanar: TRY_FMT(G_FMT) != G_FMT
  test VIDIOC_TRY_FMT: FAIL
  warn: v4l2-test-formats.cpp(834): S_FMT cannot handle
an invalid pixelformat.
  warn: v4l2-test-formats.cpp(835): This may or may not
be a problem. For more information see:
  warn: v4l2-test-formats.cpp(836):
http://www.mail-archive.com/linux-media@vger.kernel.org/msg56550.html
  fail: v4l2-test-formats.cpp(420): pix_mp.reserved not
zeroed


This is easy enough to fix.


  fail: v4l2-test-formats.cpp(851): Video Capture
Multiplanar is valid, but no S_FMT was implemented


For the FMT things: run with -T: that gives nice traces. You can also
set the debug flag: echo 2 /sys/class/video4linux/video0/debug to see all
ioctls in more detail.


Thanks for the tip, will try this.




  test VIDIOC_S_FMT: FAIL
  test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)

Codec ioctls:
  test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
  test VIDIOC_G_ENC_INDEX: OK (Not Supported)
  test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
  info: test buftype Video Capture Multiplanar
  warn: v4l2-test-buffers.cpp(403): VIDIOC_CREATE_BUFS
not supported
  info: test buftype Video Output Multiplanar
  warn: v4l2-test-buffers.cpp(403): VIDIOC_CREATE_BUFS
not supported
  test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
  test VIDIOC_EXPBUF: OK (Not Supported)
  test read/write: OK (Not Supported)
  Video Capture Multiplanar (polling):
  Buffer: 0 Sequence: 0 Field: Top Timestamp: 113.178208s
  fail: v4l2-test-buffers.cpp(222): buf.field !=
cur_fmt.fmt.pix.field


Definitely needs to be fixed, you probably just don't set the field at all.


The VPE output is always progressive. But yes, I should still set the 
field parameter to something.


Thanks,
Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 7/7] v4l: ti-vpe: Add selection API in VPE driver

2014-03-07 Thread Archit Taneja

On Friday 07 March 2014 07:02 PM, Hans Verkuil wrote:

On 03/07/2014 02:22 PM, Archit Taneja wrote:

Hi,

On Friday 07 March 2014 06:29 PM, Hans Verkuil wrote:


Do you think I can go ahead with posting the v3 patch set for 3.15, and
work on fixing the compliance issue for the -rc fixes?


It's fine to upstream this in staging, but while not all compliance errors
are fixed it can't go to drivers/media. I'm tightening the screws on that
since v4l2-compliance is getting to be such a powerful tool for ensuring
the driver complies.



But the vpe driver is already in drivers/media. How do I push these
patches if the vpe drivers is not in staging?


Oops, sorry. I got confused with Benoit's AM437x ti-vpfe patch :-)

Disregard what I said, it's OK to upstream it. But if you could just spend
some hours fixing the problems, that would really be best.


Sure, I'll try to fix these issues and then post a v3.





snip


Multiplanar: TRY_FMT(G_FMT) != G_FMT
   test VIDIOC_TRY_FMT: FAIL
   warn: v4l2-test-formats.cpp(834): S_FMT cannot handle
an invalid pixelformat.
   warn: v4l2-test-formats.cpp(835): This may or may not
be a problem. For more information see:
   warn: v4l2-test-formats.cpp(836):
http://www.mail-archive.com/linux-media@vger.kernel.org/msg56550.html
   fail: v4l2-test-formats.cpp(420): pix_mp.reserved not
zeroed


This is easy enough to fix.


   fail: v4l2-test-formats.cpp(851): Video Capture
Multiplanar is valid, but no S_FMT was implemented


For the FMT things: run with -T: that gives nice traces. You can also
set the debug flag: echo 2 /sys/class/video4linux/video0/debug to see all
ioctls in more detail.


Thanks for the tip, will try this.




   test VIDIOC_S_FMT: FAIL
   test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)

Codec ioctls:
   test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
   test VIDIOC_G_ENC_INDEX: OK (Not Supported)
   test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
   info: test buftype Video Capture Multiplanar
   warn: v4l2-test-buffers.cpp(403): VIDIOC_CREATE_BUFS
not supported
   info: test buftype Video Output Multiplanar
   warn: v4l2-test-buffers.cpp(403): VIDIOC_CREATE_BUFS
not supported
   test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
   test VIDIOC_EXPBUF: OK (Not Supported)
   test read/write: OK (Not Supported)
   Video Capture Multiplanar (polling):
   Buffer: 0 Sequence: 0 Field: Top Timestamp: 113.178208s
   fail: v4l2-test-buffers.cpp(222): buf.field !=
cur_fmt.fmt.pix.field


Definitely needs to be fixed, you probably just don't set the field at all.


The VPE output is always progressive. But yes, I should still set the
field parameter to something.


V4L2_FIELD_NONE is the correct field setting for that.


I checked the driver, it isn't setting it to V4L2_FIELD_NONE. Will fix this.

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] v4l: ti-vpe: Add crop support in VPE driver

2014-03-04 Thread Archit Taneja

Hi,

On Tuesday 04 March 2014 01:13 PM, Hans Verkuil wrote:

On 03/04/2014 08:38 AM, Archit Taneja wrote:

Hi Hans,

On Monday 03 March 2014 01:20 PM, Hans Verkuil wrote:

Hi Archit!

On 03/03/2014 08:33 AM, Archit Taneja wrote:

Add crop ioctl ops. For VPE, cropping only makes sense with the input to VPE, or
the V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE buffer type.

For the CAPTURE type, a S_CROP ioctl results in setting the crop region as the
whole image itself, hence making crop dimensions same as the pix dimensions.

Setting the crop successfully should result in re-configuration of those
registers which are affected when either source or destination dimensions
change, set_srcdst_params() is called for this purpose.

Some standard crop parameter checks are done in __vpe_try_crop().


Please use the selection ops instead: if you implement cropping with those then 
you'll
support both the selection API and the old cropping API will be implemented by 
the v4l2
core using the selection ops. Two for the price of one...



When using selection API, I was finding issues using the older cropping
API. The v4l_s_crop() ioctl func assumes that crop means compose for
output devices. However, for a m2m device. It probably makes sense to
provide the following configuration:

for V4L2_BUF_TYPE_VIDEO_OUTPUT (input to the mem to mem HW), use CROP
target(to crop the input buffer)

and, for V4L2_BUF_TYPE_VIDEO_CAPTURE(output of the mem to mem HW), use
COMPOSE target(to place the HW output into a larger region)

Don't you think forcing OUTPUT devices to 'COMPOSE' for older cropping
API is a bit limiting?


Yes, and that's why the selection API was created to work around that
limitation :-)

The old cropping API was insufficiently flexible for modern devices, so
we came up with this replacement.

Another reason why you have to implement the selection API: it's the only
way to implement your functionality.


Okay, I'll go ahead with the selection API then :)

Archit

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/7] v4l: ti-vpe: Some VPE fixes and enhancements

2014-03-04 Thread Archit Taneja
This patch set mainly consists of minor fixes for the VPE driver. These fixes
ensure the following:

- The VPE module can be inserted and removed successively.
- Make sure that smaller resolutions like qcif work correctly.
- Prevent race condition between firmware loading and an open call to the v4l2
  device.
- Prevent the possibility of output m2m queue not having sufficient 'ready'
  buffers.
- Some VPDMA data descriptor fields weren't understood correctly before. They
  are now used correctly.

The rest of the patches add some minor features like DMA buf support and
cropping/composing.

Reference branch:

g...@github.com:boddob/linux.git vpe_for_315

Changes in v2:

- selection API used instead of older cropping API.
- Typo fix.
- Some changes in patch 6/7 to support composing on the capture side of VPE.

Archit Taneja (7):
  v4l: ti-vpe: Make sure in job_ready that we have the needed number of
dst_bufs
  v4l: ti-vpe: register video device only when firmware is loaded
  v4l: ti-vpe: Use video_device_release_empty
  v4l: ti-vpe: Allow DMABUF buffer type support
  v4l: ti-vpe: Allow usage of smaller images
  v4l: ti-vpe: Fix some params in VPE data descriptors
  v4l: ti-vpe: Add selection API in VPE driver

 drivers/media/platform/ti-vpe/vpdma.c |  68 +++---
 drivers/media/platform/ti-vpe/vpdma.h |  17 +--
 drivers/media/platform/ti-vpe/vpe.c   | 228 +-
 3 files changed, 255 insertions(+), 58 deletions(-)

-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/7] v4l: ti-vpe: register video device only when firmware is loaded

2014-03-04 Thread Archit Taneja
vpe fops(vpe_open in particular) should be called only when VPDMA firmware
is loaded. File operations on the video device are possible the moment it is
registered.

Currently, we register the video device for VPE at driver probe, after calling
a vpdma helper to initialize VPDMA and load firmware. This function is
non-blocking(it calls request_firmware_nowait()), and doesn't ensure that the
firmware is actually loaded when it returns.

We remove the device registration from vpe probe, and move it to a callback
provided by the vpe driver to the vpdma library, through vpdma_create().

The ready field in vpdma_data is no longer needed since we always have firmware
loaded before the device is registered.

A minor problem with this approach is that if the video_register_device
fails(which doesn't really happen), the vpe platform device would be registered.
however, there won't be any v4l2 device corresponding to it.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpdma.c |  8 +++--
 drivers/media/platform/ti-vpe/vpdma.h |  7 +++--
 drivers/media/platform/ti-vpe/vpe.c   | 55 ---
 3 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c 
b/drivers/media/platform/ti-vpe/vpdma.c
index e8175e7..73dd38e 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -781,7 +781,7 @@ static void vpdma_firmware_cb(const struct firmware *f, 
void *context)
/* already initialized */
if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
VPDMA_LIST_RDY_SHFT)) {
-   vpdma-ready = true;
+   vpdma-cb(vpdma-pdev);
return;
}
 
@@ -811,7 +811,7 @@ static void vpdma_firmware_cb(const struct firmware *f, 
void *context)
goto free_buf;
}
 
-   vpdma-ready = true;
+   vpdma-cb(vpdma-pdev);
 
 free_buf:
vpdma_unmap_desc_buf(vpdma, fw_dma_buf);
@@ -839,7 +839,8 @@ static int vpdma_load_firmware(struct vpdma_data *vpdma)
return 0;
 }
 
-struct vpdma_data *vpdma_create(struct platform_device *pdev)
+struct vpdma_data *vpdma_create(struct platform_device *pdev,
+   void (*cb)(struct platform_device *pdev))
 {
struct resource *res;
struct vpdma_data *vpdma;
@@ -854,6 +855,7 @@ struct vpdma_data *vpdma_create(struct platform_device 
*pdev)
}
 
vpdma-pdev = pdev;
+   vpdma-cb = cb;
 
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, vpdma);
if (res == NULL) {
diff --git a/drivers/media/platform/ti-vpe/vpdma.h 
b/drivers/media/platform/ti-vpe/vpdma.h
index cf40f11..bf5f8bb 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -35,8 +35,8 @@ struct vpdma_data {
 
struct platform_device  *pdev;
 
-   /* tells whether vpdma firmware is loaded or not */
-   bool ready;
+   /* callback to VPE driver when the firmware is loaded */
+   void (*cb)(struct platform_device *pdev);
 };
 
 enum vpdma_data_format_type {
@@ -208,6 +208,7 @@ void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
 void vpdma_dump_regs(struct vpdma_data *vpdma);
 
 /* initialize vpdma, passed with VPE's platform device pointer */
-struct vpdma_data *vpdma_create(struct platform_device *pdev);
+struct vpdma_data *vpdma_create(struct platform_device *pdev,
+   void (*cb)(struct platform_device *pdev));
 
 #endif
diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 623e59e..4243687 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1815,11 +1815,6 @@ static int vpe_open(struct file *file)
 
vpe_dbg(dev, vpe_open\n);
 
-   if (!dev-vpdma-ready) {
-   vpe_err(dev, vpdma firmware not loaded\n);
-   return -ENODEV;
-   }
-
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
@@ -2037,10 +2032,40 @@ static void vpe_runtime_put(struct platform_device 
*pdev)
WARN_ON(r  0  r != -ENOSYS);
 }
 
+static void vpe_fw_cb(struct platform_device *pdev)
+{
+   struct vpe_dev *dev = platform_get_drvdata(pdev);
+   struct video_device *vfd;
+   int ret;
+
+   vfd = dev-vfd;
+   *vfd = vpe_videodev;
+   vfd-lock = dev-dev_mutex;
+   vfd-v4l2_dev = dev-v4l2_dev;
+
+   ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+   if (ret) {
+   vpe_err(dev, Failed to register video device\n);
+
+   vpe_set_clock_enable(dev, 0);
+   vpe_runtime_put(pdev);
+   pm_runtime_disable(pdev-dev);
+   v4l2_m2m_release(dev-m2m_dev);
+   vb2_dma_contig_cleanup_ctx(dev-alloc_ctx);
+   v4l2_device_unregister(dev-v4l2_dev);
+
+   return;
+   }
+
+   video_set_drvdata

[PATCH v2 5/7] v4l: ti-vpe: Allow usage of smaller images

2014-03-04 Thread Archit Taneja
The minimum width and height for VPE input/output was kept as 128 pixels. VPE
doesn't have a constraint on the image height, it requires the image width to
be at least 16 bytes.

Change the minimum supported dimensions to 32x32. This allows us to de-interlace
qcif content. A smaller image size than 32x32 didn't make much sense, so stopped
at this.

Signed-off-by: Archit Taneja arc...@ti.com
---
 drivers/media/platform/ti-vpe/vpe.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 915029b..3a610a6 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -49,8 +49,8 @@
 #define VPE_MODULE_NAME vpe
 
 /* minimum and maximum frame sizes */
-#define MIN_W  128
-#define MIN_H  128
+#define MIN_W  32
+#define MIN_H  32
 #define MAX_W  1920
 #define MAX_H  1080
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   5   6   7   8   9   10   >