Re: [PATCH] qcom-scm: Include header

2019-01-01 Thread Andy Gross
On Sat, Dec 29, 2018 at 10:19:32AM -0200, Fabio Estevam wrote:
> Hi Bjorn,
> 
> On Fri, Dec 28, 2018 at 10:27 PM Bjorn Andersson
>  wrote:
> 
> > Sorry about that, I forgot that the header file is not covered by the
> > MAINTAINERS file.
> >
> > Your second patch looks good, but I'm hoping we can merge the upcoming
> > v3 of Amit's patch right after the merge window. It fixes this and a lot
> > of other pieces where we would like to include linux-arm-msm@:
> >
> > https://lore.kernel.org/lkml/d153a86748f99526e7790bfc4ef8781a2016fd51.1545126964.git.amit.kuche...@linaro.org/
> 
> Amit's patch adds the following entry:
> 
> +F: include/linux/*/qcom*
> 
> but it does not catch include/linux/qcom_scm.h
> 
> It also needs
> 
> +F: include/linux/qcom*
> 
> in order to catch include/linux/qcom-geni-se.h  and include/linux/qcom_scm.h
> 
> I can add that entry after Amit's patch gets applied.

Or I can add it to Amit's.  I'll ping him to make sure that's ok.

Thanks,

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


Re: [v2 1/7] soc: qcom: llcc-slice: Add error checks for API functions

2018-11-15 Thread Andy Gross
On Fri, Oct 05, 2018 at 06:38:29PM +0530, Sharat Masetty wrote:
> From: Jordan Crouse 
> 
> llcc_slice_getd can return a ERR_PTR code on failure. Add a IS_ERR_OR_NULL
> check to subsequent API calls that use struct llcc_slice_desc to guard
> against faults and to let the leaf drivers get away with safely using a
> ERR_PTR() encoded "pointer" in the aftermath of a llcc_slice_getd error.
> 
> Signed-off-by: Jordan Crouse 
> Reviewed-by: Vivek Gautam 
> ---

Thanks for sending this.  I'll queue this up.

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


Re: [PATCH] firmware: qcom_scm: Add set remote state API

2017-01-24 Thread Andy Gross
On 24 January 2017 at 03:54, Stanimir Varbanov  wrote:
> Andy,
>
> Could you queue this patch for 4.11?

This patch is in the qcom-drivers-for-4.11 pull request I sent 9 hours
ago.  So you should be good.

https://www.spinics.net/lists/arm-kernel/msg557325.html
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] firmware: qcom_scm: Add set remote state API

2017-01-17 Thread Andy Gross
This patch adds a set remote state SCM API.  This will be used by the
Venus and GPU subsystems to set state on the remote processors.

This work was based on two patch sets by Jordan Crouse and Stanimir
Varbanov.

Signed-off-by: Andy Gross <andy.gr...@linaro.org>
---
 drivers/firmware/qcom_scm-32.c | 18 ++
 drivers/firmware/qcom_scm-64.c | 16 
 drivers/firmware/qcom_scm.c|  6 ++
 drivers/firmware/qcom_scm.h|  2 ++
 include/linux/qcom_scm.h   |  4 +++-
 5 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index c6aeedb..8ad226c 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -560,3 +560,21 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool 
reset)
 
return ret ? : le32_to_cpu(out);
 }
+
+int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
+{
+   struct {
+   __le32 state;
+   __le32 id;
+   } req;
+   __le32 scm_ret = 0;
+   int ret;
+
+   req.state = cpu_to_le32(state);
+   req.id = cpu_to_le32(id);
+
+   ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
+   , sizeof(req), _ret, sizeof(scm_ret));
+
+   return ret ? : le32_to_cpu(scm_ret);
+}
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index 4a0f5ea..4b220ab 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -358,3 +358,19 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool 
reset)
 
return ret ? : res.a1;
 }
+
+int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
+{
+   struct qcom_scm_desc desc = {0};
+   struct arm_smccc_res res;
+   int ret;
+
+   desc.args[0] = state;
+   desc.args[1] = id;
+   desc.arginfo = QCOM_SCM_ARGS(2);
+
+   ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
+   , );
+
+   return ret ? : res.a1;
+}
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 65d0d9d..d987bcc 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -324,6 +324,12 @@ bool qcom_scm_is_available(void)
 }
 EXPORT_SYMBOL(qcom_scm_is_available);
 
+int qcom_scm_set_remote_state(u32 state, u32 id)
+{
+   return __qcom_scm_set_remote_state(__scm->dev, state, id);
+}
+EXPORT_SYMBOL(qcom_scm_set_remote_state);
+
 static int qcom_scm_probe(struct platform_device *pdev)
 {
struct qcom_scm *scm;
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index 3584b00..6a0f154 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -15,6 +15,8 @@
 #define QCOM_SCM_SVC_BOOT  0x1
 #define QCOM_SCM_BOOT_ADDR 0x1
 #define QCOM_SCM_BOOT_ADDR_MC  0x11
+#define QCOM_SCM_SET_REMOTE_STATE  0xa
+extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id);
 
 #define QCOM_SCM_FLAG_HLOS 0x01
 #define QCOM_SCM_FLAG_COLDBOOT_MC  0x02
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index 7e004fb..d32f6f1 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -39,6 +39,7 @@ extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t 
addr,
 extern int qcom_scm_pas_shutdown(u32 peripheral);
 extern void qcom_scm_cpu_power_down(u32 flags);
 extern u32 qcom_scm_get_version(void);
+extern int qcom_scm_set_remote_state(u32 state, u32 id);
 #else
 static inline
 int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
@@ -64,6 +65,7 @@ static inline int qcom_scm_pas_mem_setup(u32 peripheral, 
phys_addr_t addr,
 static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; }
 static inline void qcom_scm_cpu_power_down(u32 flags) {}
 static inline u32 qcom_scm_get_version(void) { return 0; }
+static inline u32
+qcom_scm_set_remote_state(u32 state,u32 id) { return -ENODEV; }
 #endif
-
 #endif
-- 
1.9.1

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


Re: [Freedreno] [PATCH 10/12] firmware: qcom_scm: Add qcom_scm_gpu_zap_resume()

2017-01-17 Thread Andy Gross
On Tue, Jan 17, 2017 at 10:04:59AM -0700, Jordan Crouse wrote:
> On Sat, Jan 14, 2017 at 11:20:58PM -0600, Andy Gross wrote:
> > + Stanimir
> > 
> > On Sat, Jan 14, 2017 at 09:49:01PM -0600, Andy Gross wrote:
> > > On Fri, Jan 13, 2017 at 04:24:38PM -0700, Jordan Crouse wrote:
> > > > On Fri, Jan 13, 2017 at 11:12:41AM -0600, Andy Gross wrote:
> > > > > On Mon, Nov 28, 2016 at 12:28:35PM -0700, Jordan Crouse wrote:
> > > > > > Add an interface to trigger the remote processor to reinitialize 
> > > > > > the GPU
> > > > > > zap shader on power-up.
> > > > > > 
> > > > > > Signed-off-by: Jordan Crouse <jcro...@codeaurora.org>
> > > > > > ---
> > > > > 
> > > > > 
> > > > > 
> > > > > > +int __qcom_scm_gpu_zap_resume(struct device *dev)
> > > > > > +{
> > > > > > +   struct qcom_scm_desc desc = {0};
> > > > > > +   struct arm_smccc_res res;
> > > > > > +   int ret;
> > > > > > +
> > > > > > +   desc.args[0] = 0;
> > > > 
> > > > This is an opcode to force the state to resume.
> > > > 
> > > > QCOM_SCM_BOOT_SET_STATE_RESUME perhaps?  Or something similar but 
> > > > shorter.
> > > > 
> > > > > > +   desc.args[1] = 13;
> > > > 
> > > > This is the same as the SCM id of the GPU but I think that is a 
> > > > coincidence.
> > > > We've always used it to identify the GPU in this call.
> > > > 
> > > > QCOM_SCM_BOOT_SET_STATE_GPU would be fine here - or something similar.
> > > > 
> > > > > Can I get a define here for these two?  Or maybe a comment on what 
> > > > > these values
> > > > > are?
> > > > > 
> > > > > > +   desc.arginfo = QCOM_SCM_ARGS(2);
> > > > > > +
> > > > > > +   ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, 0x0A, , );
> > > > > 
> > > > > Same with the 0xA.  We usually throw a #define in for the command 
> > > > > definitions.
> > > > 
> > > > 0x0A sets the state of the device - for us it is always 0 (resume) and 
> > > > always
> > > > the GPU.
> > > > 
> > > > #define  QCOM_SCM_BOOT_SET_STATE 0x0A
> > > > 
> > > > > Otherwise this all looks fine.  If you can get back to me with either 
> > > > > the values
> > > > > or a new patch I can include this in the next pull.
> > > > 
> > > > I'll make the changes and start the song and dance, but you'll no doubt 
> > > > be
> > > > faster than I.
> > > 
> > > I can just fix up the patch with the above.  Thanks for the additional 
> > > details.
> > 
> > The plot thickens.  So I have a patch from Stanimir concerning another SCM 
> > call
> > that is using the same command and number of arguments.  And it also 
> > concerns
> > setting state.  I think that we need to roll a common API for setting the 
> > state
> > and then both of you can call it.  That way we can kill two birds with one
> > stone.
> 
> I was worried about this, but not this quickly - glad to see that the other
> drivers are coming along too.
> 
> If you look carefully, you'll note that the values are inverted - the video
> state uses 0 to suspend and 1 to resume, and GPU uses 0 to resume and no
> suspend. I asked why and got a bunch of shrugging back. Its not a big deal
> because your API accounts for this but expect GPU to have a RESUME #define
> that is a different value.
> 
> > Something along the lines of a function prototype:
> > int qcom_scm_set_remote_state(u32 state, u32 id)
> > {
> > return __qcom_scm_set_remote_state(__scm->dev, state, id);
> > }
> > EXPORT_SYMBOL(qcom_scm_set_remote_state);
> > 
> > where state is the state you want set, and id is the identifier of the 
> > remote
> > proc.
> >
> > Does this make sense for both of your use cases?
> 
> Yep - this is fine.

If you guys can ack/sob that patch I'd appreciate it.

As for the #defines, you guys can define whatever you like in your drivers.
This API just pushes all that into your client drivers.


Andy

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


Re: [Freedreno] [PATCH 10/12] firmware: qcom_scm: Add qcom_scm_gpu_zap_resume()

2017-01-15 Thread Andy Gross
On Fri, Jan 13, 2017 at 04:24:38PM -0700, Jordan Crouse wrote:
> On Fri, Jan 13, 2017 at 11:12:41AM -0600, Andy Gross wrote:
> > On Mon, Nov 28, 2016 at 12:28:35PM -0700, Jordan Crouse wrote:
> > > Add an interface to trigger the remote processor to reinitialize the GPU
> > > zap shader on power-up.
> > > 
> > > Signed-off-by: Jordan Crouse <jcro...@codeaurora.org>
> > > ---
> > 
> > 
> > 
> > > +int __qcom_scm_gpu_zap_resume(struct device *dev)
> > > +{
> > > + struct qcom_scm_desc desc = {0};
> > > + struct arm_smccc_res res;
> > > + int ret;
> > > +
> > > + desc.args[0] = 0;
> 
> This is an opcode to force the state to resume.
> 
> QCOM_SCM_BOOT_SET_STATE_RESUME perhaps?  Or something similar but shorter.
> 
> > > + desc.args[1] = 13;
> 
> This is the same as the SCM id of the GPU but I think that is a coincidence.
> We've always used it to identify the GPU in this call.
> 
> QCOM_SCM_BOOT_SET_STATE_GPU would be fine here - or something similar.
> 
> > Can I get a define here for these two?  Or maybe a comment on what these 
> > values
> > are?
> > 
> > > + desc.arginfo = QCOM_SCM_ARGS(2);
> > > +
> > > + ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, 0x0A, , );
> > 
> > Same with the 0xA.  We usually throw a #define in for the command 
> > definitions.
> 
> 0x0A sets the state of the device - for us it is always 0 (resume) and always
> the GPU.
> 
> #define  QCOM_SCM_BOOT_SET_STATE 0x0A
> 
> > Otherwise this all looks fine.  If you can get back to me with either the 
> > values
> > or a new patch I can include this in the next pull.
> 
> I'll make the changes and start the song and dance, but you'll no doubt be
> faster than I.

I can just fix up the patch with the above.  Thanks for the additional details.

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


Re: [Freedreno] [PATCH 10/12] firmware: qcom_scm: Add qcom_scm_gpu_zap_resume()

2017-01-15 Thread Andy Gross
+ Stanimir

On Sat, Jan 14, 2017 at 09:49:01PM -0600, Andy Gross wrote:
> On Fri, Jan 13, 2017 at 04:24:38PM -0700, Jordan Crouse wrote:
> > On Fri, Jan 13, 2017 at 11:12:41AM -0600, Andy Gross wrote:
> > > On Mon, Nov 28, 2016 at 12:28:35PM -0700, Jordan Crouse wrote:
> > > > Add an interface to trigger the remote processor to reinitialize the GPU
> > > > zap shader on power-up.
> > > > 
> > > > Signed-off-by: Jordan Crouse <jcro...@codeaurora.org>
> > > > ---
> > > 
> > > 
> > > 
> > > > +int __qcom_scm_gpu_zap_resume(struct device *dev)
> > > > +{
> > > > +   struct qcom_scm_desc desc = {0};
> > > > +   struct arm_smccc_res res;
> > > > +   int ret;
> > > > +
> > > > +   desc.args[0] = 0;
> > 
> > This is an opcode to force the state to resume.
> > 
> > QCOM_SCM_BOOT_SET_STATE_RESUME perhaps?  Or something similar but shorter.
> > 
> > > > +   desc.args[1] = 13;
> > 
> > This is the same as the SCM id of the GPU but I think that is a coincidence.
> > We've always used it to identify the GPU in this call.
> > 
> > QCOM_SCM_BOOT_SET_STATE_GPU would be fine here - or something similar.
> > 
> > > Can I get a define here for these two?  Or maybe a comment on what these 
> > > values
> > > are?
> > > 
> > > > +   desc.arginfo = QCOM_SCM_ARGS(2);
> > > > +
> > > > +   ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, 0x0A, , );
> > > 
> > > Same with the 0xA.  We usually throw a #define in for the command 
> > > definitions.
> > 
> > 0x0A sets the state of the device - for us it is always 0 (resume) and 
> > always
> > the GPU.
> > 
> > #define  QCOM_SCM_BOOT_SET_STATE 0x0A
> > 
> > > Otherwise this all looks fine.  If you can get back to me with either the 
> > > values
> > > or a new patch I can include this in the next pull.
> > 
> > I'll make the changes and start the song and dance, but you'll no doubt be
> > faster than I.
> 
> I can just fix up the patch with the above.  Thanks for the additional 
> details.

The plot thickens.  So I have a patch from Stanimir concerning another SCM call
that is using the same command and number of arguments.  And it also concerns
setting state.  I think that we need to roll a common API for setting the state
and then both of you can call it.  That way we can kill two birds with one
stone.

Something along the lines of a function prototype:
int qcom_scm_set_remote_state(u32 state, u32 id)
{
return __qcom_scm_set_remote_state(__scm->dev, state, id);
}
EXPORT_SYMBOL(qcom_scm_set_remote_state);

where state is the state you want set, and id is the identifier of the remote
proc.

Does this make sense for both of your use cases?

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


Re: [PATCH 10/12] firmware: qcom_scm: Add qcom_scm_gpu_zap_resume()

2017-01-15 Thread Andy Gross
On Mon, Nov 28, 2016 at 12:28:35PM -0700, Jordan Crouse wrote:
> Add an interface to trigger the remote processor to reinitialize the GPU
> zap shader on power-up.
> 
> Signed-off-by: Jordan Crouse 
> ---



> +int __qcom_scm_gpu_zap_resume(struct device *dev)
> +{
> + struct qcom_scm_desc desc = {0};
> + struct arm_smccc_res res;
> + int ret;
> +
> + desc.args[0] = 0;
> + desc.args[1] = 13;

Can I get a define here for these two?  Or maybe a comment on what these values
are?

> + desc.arginfo = QCOM_SCM_ARGS(2);
> +
> + ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, 0x0A, , );

Same with the 0xA.  We usually throw a #define in for the command definitions.

Otherwise this all looks fine.  If you can get back to me with either the values
or a new patch I can include this in the next pull.

Thanks.

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


Re: [PATCH 10/12] firmware: qcom_scm: Add qcom_scm_gpu_zap_resume()

2017-01-15 Thread Andy Gross
On Fri, Jan 13, 2017 at 10:22:45AM -0700, Jordan Crouse wrote:
> On Fri, Jan 13, 2017 at 11:12:41AM -0600, Andy Gross wrote:
> > On Mon, Nov 28, 2016 at 12:28:35PM -0700, Jordan Crouse wrote:
> > > Add an interface to trigger the remote processor to reinitialize the GPU
> > > zap shader on power-up.
> > > 
> > > Signed-off-by: Jordan Crouse <jcro...@codeaurora.org>
> > > ---
> > 
> > 
> > 
> > > +int __qcom_scm_gpu_zap_resume(struct device *dev)
> > > +{
> > > + struct qcom_scm_desc desc = {0};
> > > + struct arm_smccc_res res;
> > > + int ret;
> > > +
> > > + desc.args[0] = 0;
> > > + desc.args[1] = 13;
> > 
> > Can I get a define here for these two?  Or maybe a comment on what these 
> > values
> > are?
> > 
> > > + desc.arginfo = QCOM_SCM_ARGS(2);
> > > +
> > > + ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, 0x0A, , );
> > 
> > Same with the 0xA.  We usually throw a #define in for the command 
> > definitions.
> > 
> > Otherwise this all looks fine.  If you can get back to me with either the 
> > values
> > or a new patch I can include this in the next pull.
> 
> Thanks for reaching out. Since this isn't my usual area I'll need to work out
> some terminology with the SCM folks to make sure I don't accidentally do
> anything that will get me in trouble.

Yeah I did a brief look through CAF.   I saw basically the same information.  If
you can't get an answer, let me know and I'll just take it and put in a comment.


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


[PATCH] drm/msm: Fix error handling crashes seen when VRAM allocation fails

2016-11-03 Thread Andy Gross
On Thu, Nov 03, 2016 at 05:36:18PM +0530, Archit Taneja wrote:
> If VRAM allocation fails, the error handling path crashes in
> msm_drm_uninit(). The following changes are made to fix this:
> 
> msm_gem_shrinker_cleanup() is fixed to unregister the shrinker only
> if it was init-ed in the first place.
> 
> Before calling kms->funcs->destroy(), we check if kms->funcs is also
> non-NULL. This is needed for MDP5, since during msm_drm_int(), priv->kms
> becomes non-NULL early, but msm_kms_init() is called on it only later
> in mdp5_kms_init().
> 
> Signed-off-by: Archit Taneja 
> ---

Reviewed-by: Andy Gross 


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

2016-08-26 Thread Andy Gross
On Thu, Jun 23, 2016 at 07:43:30PM +0530, Archit Taneja wrote:
> The APQ8016-sbc provides a HDMI output. The APQ8016 display block only
> provides a MIPI DSI output. So, the board has a ADV7533 DSI to HDMI
> encoder chip that sits between the DSI PHY output and the HDMI
> connector.
> 
> Add the ADV7533 DT node under its I2C control bus, and tie the DSI
> output port to the ADV7533's input port.
> 
> Cc: Andy Gross 
> Cc: Rob Herring 
> Cc: devicetree at vger.kernel.org
> 
> Signed-off-by: Archit Taneja 

This also looks fine.

Regards,

Andy


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

2016-08-26 Thread Andy Gross
On Thu, Jun 23, 2016 at 07:43:29PM +0530, Archit Taneja wrote:
> The MSM8916 SoC contains a MDP5 based display block, and one DSI output.
> Add the top level MDSS DT node, and the MDP5, DSI and DSI PHY children
> sub-blocks. Establish the link between MDP5's INTF1 output port and DSI's
> input port.
> 
> Cc: Andy Gross 
> Cc: Rob Herring 
> Cc: devicetree at vger.kernel.org


This looks fine to me.


Regards,
Andy


[PATCH] drm/omap: Add device tree support to DMM

2013-03-19 Thread Andy Gross
Added in detection/support for DMM devices when booting with device
tree.

Signed-off-by: Andy Gross 
---
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c 
b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 9b794c9..d84f37c 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "omap_dmm_tiler.h"
 #include "omap_dmm_priv.h"
@@ -968,6 +969,14 @@ static const struct dev_pm_ops omap_dmm_pm_ops = {
 };
 #endif

+#ifdef CONFIG_OF
+static const struct of_device_id omap_dmm_of_match[] = {
+   {.compatible = "ti,dmm", },
+   {},
+};
+MODULE_DEVICE_TABLE(of, omap_dmm_of_match);
+#endif
+
 struct platform_driver omap_dmm_driver = {
.probe = omap_dmm_probe,
.remove = omap_dmm_remove,
@@ -977,6 +986,7 @@ struct platform_driver omap_dmm_driver = {
 #ifdef CONFIG_PM
.pm = _dmm_pm_ops,
 #endif
+   .of_match_table = of_match_ptr(omap_dmm_of_match),
},
 };

-- 
1.7.5.4



[PATCH] drm/omap: Add device tree support to DMM

2013-03-19 Thread Andy Gross
Added in detection/support for DMM devices when booting with device
tree.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c 
b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 9b794c9..d84f37c 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -29,6 +29,7 @@
 #include linux/mm.h
 #include linux/time.h
 #include linux/list.h
+#include linux/of.h
 
 #include omap_dmm_tiler.h
 #include omap_dmm_priv.h
@@ -968,6 +969,14 @@ static const struct dev_pm_ops omap_dmm_pm_ops = {
 };
 #endif
 
+#ifdef CONFIG_OF
+static const struct of_device_id omap_dmm_of_match[] = {
+   {.compatible = ti,dmm, },
+   {},
+};
+MODULE_DEVICE_TABLE(of, omap_dmm_of_match);
+#endif
+
 struct platform_driver omap_dmm_driver = {
.probe = omap_dmm_probe,
.remove = omap_dmm_remove,
@@ -977,6 +986,7 @@ struct platform_driver omap_dmm_driver = {
 #ifdef CONFIG_PM
.pm = omap_dmm_pm_ops,
 #endif
+   .of_match_table = of_match_ptr(omap_dmm_of_match),
},
 };
 
-- 
1.7.5.4

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


[PATCH 2/2] drm/omap: Add OMAP5 support

2012-12-19 Thread Andy Gross
Add support for OMAP5 processor.  The main differences are that the OMAP5
has 2 containers, one for 1D and one for 2D.  Each container is 128MiB in
size.

Signed-off-by: Andy Gross 
Signed-off-by: Rob Clark 
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 +
 drivers/staging/omapdrm/omap_dmm_tiler.c |  127 +++--
 drivers/staging/omapdrm/tcm.h|2 +
 3 files changed, 90 insertions(+), 44 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 273ec12..58bcd6a 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -118,6 +118,11 @@ struct pat {
 #define DESCR_SIZE 128
 #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE))

+/* For OMAP5, a fixed offset is added to all Y coordinates for 1D buffers.
+ * This is used in programming to address the upper portion of the LUT
+*/
+#define OMAP5_LUT_OFFSET   128
+
 struct dmm;

 struct dmm_txn {
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index c42c5e5..3910215 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -213,6 +213,11 @@ static void dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
txn->last_pat->next_pa = (uint32_t)pat_pa;

pat->area = *area;
+
+   /* adjust Y coordinates based off of container parameters */
+   pat->area.y0 += engine->tcm->y_offset;
+   pat->area.y1 += engine->tcm->y_offset;
+
pat->ctrl = (struct pat_ctrl){
.start = 1,
.lut_id = engine->tcm->lut_id,
@@ -622,6 +627,11 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5;
omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5;

+   /* increment LUT by one if on OMAP5 */
+   /* LUT has twice the height, and is split into a separate container */
+   if (omap_dmm->lut_height != omap_dmm->container_height)
+   omap_dmm->num_lut++;
+
/* initialize DMM registers */
writel(0x, omap_dmm->base + DMM_PAT_VIEW__0);
writel(0x, omap_dmm->base + DMM_PAT_VIEW__1);
@@ -701,6 +711,9 @@ static int omap_dmm_probe(struct platform_device *dev)
}

/* init containers */
+   /* Each LUT is associated with a TCM (container manager).  We use the
+  lut_id to denote the lut_id used to identify the correct LUT for
+  programming during reill operations */
for (i = 0; i < omap_dmm->num_lut; i++) {
omap_dmm->tcm[i] = sita_init(omap_dmm->container_width,
omap_dmm->container_height,
@@ -717,13 +730,23 @@ static int omap_dmm_probe(struct platform_device *dev)

/* assign access mode containers to applicable tcm container */
/* OMAP 4 has 1 container for all 4 views */
+   /* OMAP 5 has 2 containers, 1 for 2D and 1 for 1D */
containers[TILFMT_8BIT] = omap_dmm->tcm[0];
containers[TILFMT_16BIT] = omap_dmm->tcm[0];
containers[TILFMT_32BIT] = omap_dmm->tcm[0];
-   containers[TILFMT_PAGE] = omap_dmm->tcm[0];
+
+   if (omap_dmm->container_height != omap_dmm->lut_height) {
+   /* second LUT is used for PAGE mode.  Programming must use
+  y offset that is added to all y coordinates.  LUT id is still
+  0, because it is the same LUT, just the upper 128 lines */
+   containers[TILFMT_PAGE] = omap_dmm->tcm[1];
+   omap_dmm->tcm[1]->y_offset = OMAP5_LUT_OFFSET;
+   omap_dmm->tcm[1]->lut_id = 0;
+   } else {
+   containers[TILFMT_PAGE] = omap_dmm->tcm[0];
+   }

area = (struct tcm_area) {
-   .is2d = true,
.tcm = NULL,
.p1.x = omap_dmm->container_width - 1,
.p1.y = omap_dmm->container_height - 1,
@@ -835,64 +858,81 @@ int tiler_map_show(struct seq_file *s, void *arg)
int h_adj;
int w_adj;
unsigned long flags;
+   int lut_idx;
+

if (!omap_dmm) {
/* early return if dmm/tiler device is not initialized */
return 0;
}

-   h_adj = omap_dmm->lut_height / ydiv;
-   w_adj = omap_dmm->lut_width / xdiv;
+   h_adj = omap_dmm->container_height / ydiv;
+   w_adj = omap_dmm->container_width / xdiv;

-   map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL);
-   global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL);
+   map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL);
+   global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL);

if (!map || !global_map)
g

[PATCH 1/2] drm/omap: Add PM capabilities

2012-12-19 Thread Andy Gross
Added power management capabilities into the omapdrm and DMM drivers.
During suspend, we don't need to do anything to maintain the state of
the LUT.  We have all the necessary information to recreate the mappings
of the GEM object list maintained by the omapdrm driver.

On resume, the DMM resume handler will first reprogram the LUT to point
to the dummy page.  The subsequent resume handler in the omapdrm will call
into the DMM and reprogram each of the buffer objects.  This will ensure
that all of the necessary objects will be pinned into the DMM properly.

Order of suspend/resume handlers is done by device creation.  We create
the DMM device before the omapdrm, so the correct order is maintained.

Signed-off-by: Andy Gross 
Signed-off-by: Rob Clark 
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |   34 ++
 drivers/staging/omapdrm/omap_drv.c   |   14 
 drivers/staging/omapdrm/omap_drv.h   |4 +++
 drivers/staging/omapdrm/omap_gem.c   |   28 
 4 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 59bf438..c42c5e5 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -903,12 +903,46 @@ error:
 }
 #endif

+#ifdef CONFIG_PM
+static int omap_dmm_resume(struct device *dev)
+{
+   struct tcm_area area;
+   int i;
+
+   if (!omap_dmm)
+   return -ENODEV;
+
+   area = (struct tcm_area) {
+   .is2d = true,
+   .tcm = NULL,
+   .p1.x = omap_dmm->container_width - 1,
+   .p1.y = omap_dmm->container_height - 1,
+   };
+
+   /* initialize all LUTs to dummy page entries */
+   for (i = 0; i < omap_dmm->num_lut; i++) {
+   area.tcm = omap_dmm->tcm[i];
+   if (fill(, NULL, 0, 0, true))
+   dev_err(dev, "refill failed");
+   }
+
+   return 0;
+}
+
+static const struct dev_pm_ops omap_dmm_pm_ops = {
+   .resume = omap_dmm_resume,
+};
+#endif
+
 struct platform_driver omap_dmm_driver = {
.probe = omap_dmm_probe,
.remove = omap_dmm_remove,
.driver = {
.owner = THIS_MODULE,
.name = DMM_DRIVER_NAME,
+#ifdef CONFIG_PM
+   .pm = _dmm_pm_ops,
+#endif
},
 };

diff --git a/drivers/staging/omapdrm/omap_drv.c 
b/drivers/staging/omapdrm/omap_drv.c
index ae5ecc2..d246f85 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -368,6 +368,9 @@ static int dev_load(struct drm_device *dev, unsigned long 
flags)
/* well, limp along without an fbdev.. maybe X11 will work? */
}

+   /* store off drm_device for use in pm ops */
+   dev_set_drvdata(dev->dev, dev);
+
drm_kms_helper_poll_init(dev);

return 0;
@@ -393,6 +396,8 @@ static int dev_unload(struct drm_device *dev)
kfree(dev->dev_private);
dev->dev_private = NULL;

+   dev_set_drvdata(dev->dev, NULL);
+
return 0;
 }

@@ -558,10 +563,19 @@ static int pdev_remove(struct platform_device *device)
return 0;
 }

+#ifdef CONFIG_PM
+static const struct dev_pm_ops omapdrm_pm_ops = {
+   .resume = omap_gem_resume,
+};
+#endif
+
 struct platform_driver pdev = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+   .pm = _pm_ops,
+#endif
},
.probe = pdev_probe,
.remove = pdev_remove,
diff --git a/drivers/staging/omapdrm/omap_drv.h 
b/drivers/staging/omapdrm/omap_drv.h
index cd1f22b..f921027 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -135,6 +135,10 @@ void omap_gem_describe(struct drm_gem_object *obj, struct 
seq_file *m);
 void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
 #endif

+#ifdef CONFIG_PM
+int omap_gem_resume(struct device *dev);
+#endif
+
 int omap_irq_enable_vblank(struct drm_device *dev, int crtc);
 void omap_irq_disable_vblank(struct drm_device *dev, int crtc);
 irqreturn_t omap_irq_handler(DRM_IRQ_ARGS);
diff --git a/drivers/staging/omapdrm/omap_gem.c 
b/drivers/staging/omapdrm/omap_gem.c
index c38992b..08f1e292 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -964,6 +964,34 @@ void *omap_gem_vaddr(struct drm_gem_object *obj)
return omap_obj->vaddr;
 }

+#ifdef CONFIG_PM
+/* re-pin objects in DMM in resume path: */
+int omap_gem_resume(struct device *dev)
+{
+   struct drm_device *drm_dev = dev_get_drvdata(dev);
+   struct omap_drm_private *priv = drm_dev->dev_private;
+   struct omap_gem_object *omap_obj;
+   int ret = 0;
+
+   list_for_each_entry(omap_obj, >obj_list, 

[PATCH v2 0/2] drm/omap: Add PM and OMAP5 support

2012-12-19 Thread Andy Gross
First patch adds PM capabilities for omapdrm.  Second patch adds
OMAP5 support to DMM driver component.

Series was build tested and based on linux-next.

v2: Updated commit msg for PM patch

Andy Gross (2):
  drm/omap: Add PM capabilities
  drm/omap: Add OMAP5 support

 drivers/staging/omapdrm/omap_dmm_priv.h  |5 +
 drivers/staging/omapdrm/omap_dmm_tiler.c |  159 ++
 drivers/staging/omapdrm/omap_drv.c   |   14 +++
 drivers/staging/omapdrm/omap_drv.h   |4 +
 drivers/staging/omapdrm/omap_gem.c   |   28 +
 drivers/staging/omapdrm/tcm.h|2 +
 6 files changed, 169 insertions(+), 43 deletions(-)

-- 
1.7.5.4



[PATCH v2 0/2] drm/omap: Add PM and OMAP5 support

2012-12-19 Thread Andy Gross
First patch adds PM capabilities for omapdrm.  Second patch adds
OMAP5 support to DMM driver component.

Series was build tested and based on linux-next.

v2: Updated commit msg for PM patch

Andy Gross (2):
  drm/omap: Add PM capabilities
  drm/omap: Add OMAP5 support

 drivers/staging/omapdrm/omap_dmm_priv.h  |5 +
 drivers/staging/omapdrm/omap_dmm_tiler.c |  159 ++
 drivers/staging/omapdrm/omap_drv.c   |   14 +++
 drivers/staging/omapdrm/omap_drv.h   |4 +
 drivers/staging/omapdrm/omap_gem.c   |   28 +
 drivers/staging/omapdrm/tcm.h|2 +
 6 files changed, 169 insertions(+), 43 deletions(-)

-- 
1.7.5.4

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


[PATCH 2/2] drm/omap: Add OMAP5 support

2012-12-19 Thread Andy Gross
Add support for OMAP5 processor.  The main differences are that the OMAP5
has 2 containers, one for 1D and one for 2D.  Each container is 128MiB in
size.

Signed-off-by: Andy Gross andy.gr...@ti.com
Signed-off-by: Rob Clark r...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 +
 drivers/staging/omapdrm/omap_dmm_tiler.c |  127 +++--
 drivers/staging/omapdrm/tcm.h|2 +
 3 files changed, 90 insertions(+), 44 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 273ec12..58bcd6a 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -118,6 +118,11 @@ struct pat {
 #define DESCR_SIZE 128
 #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE))
 
+/* For OMAP5, a fixed offset is added to all Y coordinates for 1D buffers.
+ * This is used in programming to address the upper portion of the LUT
+*/
+#define OMAP5_LUT_OFFSET   128
+
 struct dmm;
 
 struct dmm_txn {
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index c42c5e5..3910215 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -213,6 +213,11 @@ static void dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
txn-last_pat-next_pa = (uint32_t)pat_pa;
 
pat-area = *area;
+
+   /* adjust Y coordinates based off of container parameters */
+   pat-area.y0 += engine-tcm-y_offset;
+   pat-area.y1 += engine-tcm-y_offset;
+
pat-ctrl = (struct pat_ctrl){
.start = 1,
.lut_id = engine-tcm-lut_id,
@@ -622,6 +627,11 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm-lut_width = ((pat_geom  16)  0xF)  5;
omap_dmm-lut_height = ((pat_geom  24)  0xF)  5;
 
+   /* increment LUT by one if on OMAP5 */
+   /* LUT has twice the height, and is split into a separate container */
+   if (omap_dmm-lut_height != omap_dmm-container_height)
+   omap_dmm-num_lut++;
+
/* initialize DMM registers */
writel(0x, omap_dmm-base + DMM_PAT_VIEW__0);
writel(0x, omap_dmm-base + DMM_PAT_VIEW__1);
@@ -701,6 +711,9 @@ static int omap_dmm_probe(struct platform_device *dev)
}
 
/* init containers */
+   /* Each LUT is associated with a TCM (container manager).  We use the
+  lut_id to denote the lut_id used to identify the correct LUT for
+  programming during reill operations */
for (i = 0; i  omap_dmm-num_lut; i++) {
omap_dmm-tcm[i] = sita_init(omap_dmm-container_width,
omap_dmm-container_height,
@@ -717,13 +730,23 @@ static int omap_dmm_probe(struct platform_device *dev)
 
/* assign access mode containers to applicable tcm container */
/* OMAP 4 has 1 container for all 4 views */
+   /* OMAP 5 has 2 containers, 1 for 2D and 1 for 1D */
containers[TILFMT_8BIT] = omap_dmm-tcm[0];
containers[TILFMT_16BIT] = omap_dmm-tcm[0];
containers[TILFMT_32BIT] = omap_dmm-tcm[0];
-   containers[TILFMT_PAGE] = omap_dmm-tcm[0];
+
+   if (omap_dmm-container_height != omap_dmm-lut_height) {
+   /* second LUT is used for PAGE mode.  Programming must use
+  y offset that is added to all y coordinates.  LUT id is still
+  0, because it is the same LUT, just the upper 128 lines */
+   containers[TILFMT_PAGE] = omap_dmm-tcm[1];
+   omap_dmm-tcm[1]-y_offset = OMAP5_LUT_OFFSET;
+   omap_dmm-tcm[1]-lut_id = 0;
+   } else {
+   containers[TILFMT_PAGE] = omap_dmm-tcm[0];
+   }
 
area = (struct tcm_area) {
-   .is2d = true,
.tcm = NULL,
.p1.x = omap_dmm-container_width - 1,
.p1.y = omap_dmm-container_height - 1,
@@ -835,64 +858,81 @@ int tiler_map_show(struct seq_file *s, void *arg)
int h_adj;
int w_adj;
unsigned long flags;
+   int lut_idx;
+
 
if (!omap_dmm) {
/* early return if dmm/tiler device is not initialized */
return 0;
}
 
-   h_adj = omap_dmm-lut_height / ydiv;
-   w_adj = omap_dmm-lut_width / xdiv;
+   h_adj = omap_dmm-container_height / ydiv;
+   w_adj = omap_dmm-container_width / xdiv;
 
-   map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL);
-   global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL);
+   map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL);
+   global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL);
 
if (!map || !global_map)
goto error;
 
-   memset(global_map, ' ', (w_adj + 1) * h_adj);
-   for (i = 0; i  omap_dmm-lut_height; i++) {
-   map[i] = global_map + i * (w_adj + 1

[PATCH 1/2] drm/omap: Add PM capabilities

2012-12-19 Thread Andy Gross
Added power management capabilities into the omapdrm and DMM drivers.
During suspend, we don't need to do anything to maintain the state of
the LUT.  We have all the necessary information to recreate the mappings
of the GEM object list maintained by the omapdrm driver.

On resume, the DMM resume handler will first reprogram the LUT to point
to the dummy page.  The subsequent resume handler in the omapdrm will call
into the DMM and reprogram each of the buffer objects.  This will ensure
that all of the necessary objects will be pinned into the DMM properly.

Order of suspend/resume handlers is done by device creation.  We create
the DMM device before the omapdrm, so the correct order is maintained.

Signed-off-by: Andy Gross andy.gr...@ti.com
Signed-off-by: Rob Clark r...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |   34 ++
 drivers/staging/omapdrm/omap_drv.c   |   14 
 drivers/staging/omapdrm/omap_drv.h   |4 +++
 drivers/staging/omapdrm/omap_gem.c   |   28 
 4 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 59bf438..c42c5e5 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -903,12 +903,46 @@ error:
 }
 #endif
 
+#ifdef CONFIG_PM
+static int omap_dmm_resume(struct device *dev)
+{
+   struct tcm_area area;
+   int i;
+
+   if (!omap_dmm)
+   return -ENODEV;
+
+   area = (struct tcm_area) {
+   .is2d = true,
+   .tcm = NULL,
+   .p1.x = omap_dmm-container_width - 1,
+   .p1.y = omap_dmm-container_height - 1,
+   };
+
+   /* initialize all LUTs to dummy page entries */
+   for (i = 0; i  omap_dmm-num_lut; i++) {
+   area.tcm = omap_dmm-tcm[i];
+   if (fill(area, NULL, 0, 0, true))
+   dev_err(dev, refill failed);
+   }
+
+   return 0;
+}
+
+static const struct dev_pm_ops omap_dmm_pm_ops = {
+   .resume = omap_dmm_resume,
+};
+#endif
+
 struct platform_driver omap_dmm_driver = {
.probe = omap_dmm_probe,
.remove = omap_dmm_remove,
.driver = {
.owner = THIS_MODULE,
.name = DMM_DRIVER_NAME,
+#ifdef CONFIG_PM
+   .pm = omap_dmm_pm_ops,
+#endif
},
 };
 
diff --git a/drivers/staging/omapdrm/omap_drv.c 
b/drivers/staging/omapdrm/omap_drv.c
index ae5ecc2..d246f85 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -368,6 +368,9 @@ static int dev_load(struct drm_device *dev, unsigned long 
flags)
/* well, limp along without an fbdev.. maybe X11 will work? */
}
 
+   /* store off drm_device for use in pm ops */
+   dev_set_drvdata(dev-dev, dev);
+
drm_kms_helper_poll_init(dev);
 
return 0;
@@ -393,6 +396,8 @@ static int dev_unload(struct drm_device *dev)
kfree(dev-dev_private);
dev-dev_private = NULL;
 
+   dev_set_drvdata(dev-dev, NULL);
+
return 0;
 }
 
@@ -558,10 +563,19 @@ static int pdev_remove(struct platform_device *device)
return 0;
 }
 
+#ifdef CONFIG_PM
+static const struct dev_pm_ops omapdrm_pm_ops = {
+   .resume = omap_gem_resume,
+};
+#endif
+
 struct platform_driver pdev = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+   .pm = omapdrm_pm_ops,
+#endif
},
.probe = pdev_probe,
.remove = pdev_remove,
diff --git a/drivers/staging/omapdrm/omap_drv.h 
b/drivers/staging/omapdrm/omap_drv.h
index cd1f22b..f921027 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -135,6 +135,10 @@ void omap_gem_describe(struct drm_gem_object *obj, struct 
seq_file *m);
 void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
 #endif
 
+#ifdef CONFIG_PM
+int omap_gem_resume(struct device *dev);
+#endif
+
 int omap_irq_enable_vblank(struct drm_device *dev, int crtc);
 void omap_irq_disable_vblank(struct drm_device *dev, int crtc);
 irqreturn_t omap_irq_handler(DRM_IRQ_ARGS);
diff --git a/drivers/staging/omapdrm/omap_gem.c 
b/drivers/staging/omapdrm/omap_gem.c
index c38992b..08f1e292 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -964,6 +964,34 @@ void *omap_gem_vaddr(struct drm_gem_object *obj)
return omap_obj-vaddr;
 }
 
+#ifdef CONFIG_PM
+/* re-pin objects in DMM in resume path: */
+int omap_gem_resume(struct device *dev)
+{
+   struct drm_device *drm_dev = dev_get_drvdata(dev);
+   struct omap_drm_private *priv = drm_dev-dev_private;
+   struct omap_gem_object *omap_obj;
+   int ret = 0;
+
+   list_for_each_entry(omap_obj, priv-obj_list, mm_list

[PATCH 2/2] drm/omap: Add OMAP5 support

2012-12-18 Thread Andy Gross
Add support for OMAP5 processor.  The main differences are that the OMAP5
has 2 containers, one for 1D and one for 2D.  Each container is 128MiB in
size.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 +
 drivers/staging/omapdrm/omap_dmm_tiler.c |  127 +++--
 drivers/staging/omapdrm/tcm.h|2 +
 3 files changed, 90 insertions(+), 44 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 273ec12..58bcd6a 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -118,6 +118,11 @@ struct pat {
 #define DESCR_SIZE 128
 #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE))

+/* For OMAP5, a fixed offset is added to all Y coordinates for 1D buffers.
+ * This is used in programming to address the upper portion of the LUT
+*/
+#define OMAP5_LUT_OFFSET   128
+
 struct dmm;

 struct dmm_txn {
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index c42c5e5..3910215 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -213,6 +213,11 @@ static void dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
txn->last_pat->next_pa = (uint32_t)pat_pa;

pat->area = *area;
+
+   /* adjust Y coordinates based off of container parameters */
+   pat->area.y0 += engine->tcm->y_offset;
+   pat->area.y1 += engine->tcm->y_offset;
+
pat->ctrl = (struct pat_ctrl){
.start = 1,
.lut_id = engine->tcm->lut_id,
@@ -622,6 +627,11 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5;
omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5;

+   /* increment LUT by one if on OMAP5 */
+   /* LUT has twice the height, and is split into a separate container */
+   if (omap_dmm->lut_height != omap_dmm->container_height)
+   omap_dmm->num_lut++;
+
/* initialize DMM registers */
writel(0x, omap_dmm->base + DMM_PAT_VIEW__0);
writel(0x, omap_dmm->base + DMM_PAT_VIEW__1);
@@ -701,6 +711,9 @@ static int omap_dmm_probe(struct platform_device *dev)
}

/* init containers */
+   /* Each LUT is associated with a TCM (container manager).  We use the
+  lut_id to denote the lut_id used to identify the correct LUT for
+  programming during reill operations */
for (i = 0; i < omap_dmm->num_lut; i++) {
omap_dmm->tcm[i] = sita_init(omap_dmm->container_width,
omap_dmm->container_height,
@@ -717,13 +730,23 @@ static int omap_dmm_probe(struct platform_device *dev)

/* assign access mode containers to applicable tcm container */
/* OMAP 4 has 1 container for all 4 views */
+   /* OMAP 5 has 2 containers, 1 for 2D and 1 for 1D */
containers[TILFMT_8BIT] = omap_dmm->tcm[0];
containers[TILFMT_16BIT] = omap_dmm->tcm[0];
containers[TILFMT_32BIT] = omap_dmm->tcm[0];
-   containers[TILFMT_PAGE] = omap_dmm->tcm[0];
+
+   if (omap_dmm->container_height != omap_dmm->lut_height) {
+   /* second LUT is used for PAGE mode.  Programming must use
+  y offset that is added to all y coordinates.  LUT id is still
+  0, because it is the same LUT, just the upper 128 lines */
+   containers[TILFMT_PAGE] = omap_dmm->tcm[1];
+   omap_dmm->tcm[1]->y_offset = OMAP5_LUT_OFFSET;
+   omap_dmm->tcm[1]->lut_id = 0;
+   } else {
+   containers[TILFMT_PAGE] = omap_dmm->tcm[0];
+   }

area = (struct tcm_area) {
-   .is2d = true,
.tcm = NULL,
.p1.x = omap_dmm->container_width - 1,
.p1.y = omap_dmm->container_height - 1,
@@ -835,64 +858,81 @@ int tiler_map_show(struct seq_file *s, void *arg)
int h_adj;
int w_adj;
unsigned long flags;
+   int lut_idx;
+

if (!omap_dmm) {
/* early return if dmm/tiler device is not initialized */
return 0;
}

-   h_adj = omap_dmm->lut_height / ydiv;
-   w_adj = omap_dmm->lut_width / xdiv;
+   h_adj = omap_dmm->container_height / ydiv;
+   w_adj = omap_dmm->container_width / xdiv;

-   map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL);
-   global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL);
+   map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL);
+   global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL);

if (!map || !global_map)
goto error;

-

[PATCH 1/2] drm/omap: Add PM capabilities

2012-12-18 Thread Andy Gross
Added resume hooks that will be called on resuming from DEVICE_OFF.
The dmm portion of the patch reprograms the LUT to point to the dummy
pages.  The omapdrm portion of the patch repins the buffers into the
DMM.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |   34 ++
 drivers/staging/omapdrm/omap_drv.c   |   14 
 drivers/staging/omapdrm/omap_drv.h   |4 +++
 drivers/staging/omapdrm/omap_gem.c   |   28 
 4 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 59bf438..c42c5e5 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -903,12 +903,46 @@ error:
 }
 #endif

+#ifdef CONFIG_PM
+static int omap_dmm_resume(struct device *dev)
+{
+   struct tcm_area area;
+   int i;
+
+   if (!omap_dmm)
+   return -ENODEV;
+
+   area = (struct tcm_area) {
+   .is2d = true,
+   .tcm = NULL,
+   .p1.x = omap_dmm->container_width - 1,
+   .p1.y = omap_dmm->container_height - 1,
+   };
+
+   /* initialize all LUTs to dummy page entries */
+   for (i = 0; i < omap_dmm->num_lut; i++) {
+   area.tcm = omap_dmm->tcm[i];
+   if (fill(, NULL, 0, 0, true))
+   dev_err(dev, "refill failed");
+   }
+
+   return 0;
+}
+
+static const struct dev_pm_ops omap_dmm_pm_ops = {
+   .resume = omap_dmm_resume,
+};
+#endif
+
 struct platform_driver omap_dmm_driver = {
.probe = omap_dmm_probe,
.remove = omap_dmm_remove,
.driver = {
.owner = THIS_MODULE,
.name = DMM_DRIVER_NAME,
+#ifdef CONFIG_PM
+   .pm = _dmm_pm_ops,
+#endif
},
 };

diff --git a/drivers/staging/omapdrm/omap_drv.c 
b/drivers/staging/omapdrm/omap_drv.c
index ae5ecc2..d246f85 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -368,6 +368,9 @@ static int dev_load(struct drm_device *dev, unsigned long 
flags)
/* well, limp along without an fbdev.. maybe X11 will work? */
}

+   /* store off drm_device for use in pm ops */
+   dev_set_drvdata(dev->dev, dev);
+
drm_kms_helper_poll_init(dev);

return 0;
@@ -393,6 +396,8 @@ static int dev_unload(struct drm_device *dev)
kfree(dev->dev_private);
dev->dev_private = NULL;

+   dev_set_drvdata(dev->dev, NULL);
+
return 0;
 }

@@ -558,10 +563,19 @@ static int pdev_remove(struct platform_device *device)
return 0;
 }

+#ifdef CONFIG_PM
+static const struct dev_pm_ops omapdrm_pm_ops = {
+   .resume = omap_gem_resume,
+};
+#endif
+
 struct platform_driver pdev = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+   .pm = _pm_ops,
+#endif
},
.probe = pdev_probe,
.remove = pdev_remove,
diff --git a/drivers/staging/omapdrm/omap_drv.h 
b/drivers/staging/omapdrm/omap_drv.h
index cd1f22b..f921027 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -135,6 +135,10 @@ void omap_gem_describe(struct drm_gem_object *obj, struct 
seq_file *m);
 void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
 #endif

+#ifdef CONFIG_PM
+int omap_gem_resume(struct device *dev);
+#endif
+
 int omap_irq_enable_vblank(struct drm_device *dev, int crtc);
 void omap_irq_disable_vblank(struct drm_device *dev, int crtc);
 irqreturn_t omap_irq_handler(DRM_IRQ_ARGS);
diff --git a/drivers/staging/omapdrm/omap_gem.c 
b/drivers/staging/omapdrm/omap_gem.c
index c38992b..08f1e292 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -964,6 +964,34 @@ void *omap_gem_vaddr(struct drm_gem_object *obj)
return omap_obj->vaddr;
 }

+#ifdef CONFIG_PM
+/* re-pin objects in DMM in resume path: */
+int omap_gem_resume(struct device *dev)
+{
+   struct drm_device *drm_dev = dev_get_drvdata(dev);
+   struct omap_drm_private *priv = drm_dev->dev_private;
+   struct omap_gem_object *omap_obj;
+   int ret = 0;
+
+   list_for_each_entry(omap_obj, >obj_list, mm_list) {
+   if (omap_obj->block) {
+   struct drm_gem_object *obj = _obj->base;
+   uint32_t npages = obj->size >> PAGE_SHIFT;
+   WARN_ON(!omap_obj->pages);  /* this can't happen */
+   ret = tiler_pin(omap_obj->block,
+   omap_obj->pages, npages,
+   omap_obj->roll, true);
+   if (ret) {

[PATCH 0/2] drm/omap: Add PM and OMAP5 support

2012-12-18 Thread Andy Gross
First patch adds PM capabilities for omapdrm.  Second patch adds
OMAP5 support to DMM driver component.

Series was build tested and based on linux-next.

Andy Gross (2):
  drm/omap: Add PM capabilities
  drm/omap: Add OMAP5 support

 drivers/staging/omapdrm/omap_dmm_priv.h  |5 +
 drivers/staging/omapdrm/omap_dmm_tiler.c |  159 ++
 drivers/staging/omapdrm/omap_drv.c   |   14 +++
 drivers/staging/omapdrm/omap_drv.h   |4 +
 drivers/staging/omapdrm/omap_gem.c   |   28 +
 drivers/staging/omapdrm/tcm.h|2 +
 6 files changed, 169 insertions(+), 43 deletions(-)

-- 
1.7.5.4



[PATCH 1/2] drm/omap: Add PM capabilities

2012-12-17 Thread Andy Gross
Added resume hooks that will be called on resuming from DEVICE_OFF.
The dmm portion of the patch reprograms the LUT to point to the dummy
pages.  The omapdrm portion of the patch repins the buffers into the
DMM.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |   34 ++
 drivers/staging/omapdrm/omap_drv.c   |   14 
 drivers/staging/omapdrm/omap_drv.h   |4 +++
 drivers/staging/omapdrm/omap_gem.c   |   28 
 4 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 59bf438..c42c5e5 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -903,12 +903,46 @@ error:
 }
 #endif
 
+#ifdef CONFIG_PM
+static int omap_dmm_resume(struct device *dev)
+{
+   struct tcm_area area;
+   int i;
+
+   if (!omap_dmm)
+   return -ENODEV;
+
+   area = (struct tcm_area) {
+   .is2d = true,
+   .tcm = NULL,
+   .p1.x = omap_dmm-container_width - 1,
+   .p1.y = omap_dmm-container_height - 1,
+   };
+
+   /* initialize all LUTs to dummy page entries */
+   for (i = 0; i  omap_dmm-num_lut; i++) {
+   area.tcm = omap_dmm-tcm[i];
+   if (fill(area, NULL, 0, 0, true))
+   dev_err(dev, refill failed);
+   }
+
+   return 0;
+}
+
+static const struct dev_pm_ops omap_dmm_pm_ops = {
+   .resume = omap_dmm_resume,
+};
+#endif
+
 struct platform_driver omap_dmm_driver = {
.probe = omap_dmm_probe,
.remove = omap_dmm_remove,
.driver = {
.owner = THIS_MODULE,
.name = DMM_DRIVER_NAME,
+#ifdef CONFIG_PM
+   .pm = omap_dmm_pm_ops,
+#endif
},
 };
 
diff --git a/drivers/staging/omapdrm/omap_drv.c 
b/drivers/staging/omapdrm/omap_drv.c
index ae5ecc2..d246f85 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -368,6 +368,9 @@ static int dev_load(struct drm_device *dev, unsigned long 
flags)
/* well, limp along without an fbdev.. maybe X11 will work? */
}
 
+   /* store off drm_device for use in pm ops */
+   dev_set_drvdata(dev-dev, dev);
+
drm_kms_helper_poll_init(dev);
 
return 0;
@@ -393,6 +396,8 @@ static int dev_unload(struct drm_device *dev)
kfree(dev-dev_private);
dev-dev_private = NULL;
 
+   dev_set_drvdata(dev-dev, NULL);
+
return 0;
 }
 
@@ -558,10 +563,19 @@ static int pdev_remove(struct platform_device *device)
return 0;
 }
 
+#ifdef CONFIG_PM
+static const struct dev_pm_ops omapdrm_pm_ops = {
+   .resume = omap_gem_resume,
+};
+#endif
+
 struct platform_driver pdev = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+   .pm = omapdrm_pm_ops,
+#endif
},
.probe = pdev_probe,
.remove = pdev_remove,
diff --git a/drivers/staging/omapdrm/omap_drv.h 
b/drivers/staging/omapdrm/omap_drv.h
index cd1f22b..f921027 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -135,6 +135,10 @@ void omap_gem_describe(struct drm_gem_object *obj, struct 
seq_file *m);
 void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
 #endif
 
+#ifdef CONFIG_PM
+int omap_gem_resume(struct device *dev);
+#endif
+
 int omap_irq_enable_vblank(struct drm_device *dev, int crtc);
 void omap_irq_disable_vblank(struct drm_device *dev, int crtc);
 irqreturn_t omap_irq_handler(DRM_IRQ_ARGS);
diff --git a/drivers/staging/omapdrm/omap_gem.c 
b/drivers/staging/omapdrm/omap_gem.c
index c38992b..08f1e292 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -964,6 +964,34 @@ void *omap_gem_vaddr(struct drm_gem_object *obj)
return omap_obj-vaddr;
 }
 
+#ifdef CONFIG_PM
+/* re-pin objects in DMM in resume path: */
+int omap_gem_resume(struct device *dev)
+{
+   struct drm_device *drm_dev = dev_get_drvdata(dev);
+   struct omap_drm_private *priv = drm_dev-dev_private;
+   struct omap_gem_object *omap_obj;
+   int ret = 0;
+
+   list_for_each_entry(omap_obj, priv-obj_list, mm_list) {
+   if (omap_obj-block) {
+   struct drm_gem_object *obj = omap_obj-base;
+   uint32_t npages = obj-size  PAGE_SHIFT;
+   WARN_ON(!omap_obj-pages);  /* this can't happen */
+   ret = tiler_pin(omap_obj-block,
+   omap_obj-pages, npages,
+   omap_obj-roll, true);
+   if (ret) {
+   dev_err(dev, could not repin: %d\n, ret

[PATCH 0/2] drm/omap: Add PM and OMAP5 support

2012-12-17 Thread Andy Gross
First patch adds PM capabilities for omapdrm.  Second patch adds
OMAP5 support to DMM driver component.

Series was build tested and based on linux-next.

Andy Gross (2):
  drm/omap: Add PM capabilities
  drm/omap: Add OMAP5 support

 drivers/staging/omapdrm/omap_dmm_priv.h  |5 +
 drivers/staging/omapdrm/omap_dmm_tiler.c |  159 ++
 drivers/staging/omapdrm/omap_drv.c   |   14 +++
 drivers/staging/omapdrm/omap_drv.h   |4 +
 drivers/staging/omapdrm/omap_gem.c   |   28 +
 drivers/staging/omapdrm/tcm.h|2 +
 6 files changed, 169 insertions(+), 43 deletions(-)

-- 
1.7.5.4

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


[PATCH 2/2] drm/omap: Add OMAP5 support

2012-12-17 Thread Andy Gross
Add support for OMAP5 processor.  The main differences are that the OMAP5
has 2 containers, one for 1D and one for 2D.  Each container is 128MiB in
size.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 +
 drivers/staging/omapdrm/omap_dmm_tiler.c |  127 +++--
 drivers/staging/omapdrm/tcm.h|2 +
 3 files changed, 90 insertions(+), 44 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 273ec12..58bcd6a 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -118,6 +118,11 @@ struct pat {
 #define DESCR_SIZE 128
 #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE))
 
+/* For OMAP5, a fixed offset is added to all Y coordinates for 1D buffers.
+ * This is used in programming to address the upper portion of the LUT
+*/
+#define OMAP5_LUT_OFFSET   128
+
 struct dmm;
 
 struct dmm_txn {
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index c42c5e5..3910215 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -213,6 +213,11 @@ static void dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
txn-last_pat-next_pa = (uint32_t)pat_pa;
 
pat-area = *area;
+
+   /* adjust Y coordinates based off of container parameters */
+   pat-area.y0 += engine-tcm-y_offset;
+   pat-area.y1 += engine-tcm-y_offset;
+
pat-ctrl = (struct pat_ctrl){
.start = 1,
.lut_id = engine-tcm-lut_id,
@@ -622,6 +627,11 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm-lut_width = ((pat_geom  16)  0xF)  5;
omap_dmm-lut_height = ((pat_geom  24)  0xF)  5;
 
+   /* increment LUT by one if on OMAP5 */
+   /* LUT has twice the height, and is split into a separate container */
+   if (omap_dmm-lut_height != omap_dmm-container_height)
+   omap_dmm-num_lut++;
+
/* initialize DMM registers */
writel(0x, omap_dmm-base + DMM_PAT_VIEW__0);
writel(0x, omap_dmm-base + DMM_PAT_VIEW__1);
@@ -701,6 +711,9 @@ static int omap_dmm_probe(struct platform_device *dev)
}
 
/* init containers */
+   /* Each LUT is associated with a TCM (container manager).  We use the
+  lut_id to denote the lut_id used to identify the correct LUT for
+  programming during reill operations */
for (i = 0; i  omap_dmm-num_lut; i++) {
omap_dmm-tcm[i] = sita_init(omap_dmm-container_width,
omap_dmm-container_height,
@@ -717,13 +730,23 @@ static int omap_dmm_probe(struct platform_device *dev)
 
/* assign access mode containers to applicable tcm container */
/* OMAP 4 has 1 container for all 4 views */
+   /* OMAP 5 has 2 containers, 1 for 2D and 1 for 1D */
containers[TILFMT_8BIT] = omap_dmm-tcm[0];
containers[TILFMT_16BIT] = omap_dmm-tcm[0];
containers[TILFMT_32BIT] = omap_dmm-tcm[0];
-   containers[TILFMT_PAGE] = omap_dmm-tcm[0];
+
+   if (omap_dmm-container_height != omap_dmm-lut_height) {
+   /* second LUT is used for PAGE mode.  Programming must use
+  y offset that is added to all y coordinates.  LUT id is still
+  0, because it is the same LUT, just the upper 128 lines */
+   containers[TILFMT_PAGE] = omap_dmm-tcm[1];
+   omap_dmm-tcm[1]-y_offset = OMAP5_LUT_OFFSET;
+   omap_dmm-tcm[1]-lut_id = 0;
+   } else {
+   containers[TILFMT_PAGE] = omap_dmm-tcm[0];
+   }
 
area = (struct tcm_area) {
-   .is2d = true,
.tcm = NULL,
.p1.x = omap_dmm-container_width - 1,
.p1.y = omap_dmm-container_height - 1,
@@ -835,64 +858,81 @@ int tiler_map_show(struct seq_file *s, void *arg)
int h_adj;
int w_adj;
unsigned long flags;
+   int lut_idx;
+
 
if (!omap_dmm) {
/* early return if dmm/tiler device is not initialized */
return 0;
}
 
-   h_adj = omap_dmm-lut_height / ydiv;
-   w_adj = omap_dmm-lut_width / xdiv;
+   h_adj = omap_dmm-container_height / ydiv;
+   w_adj = omap_dmm-container_width / xdiv;
 
-   map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL);
-   global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL);
+   map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL);
+   global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL);
 
if (!map || !global_map)
goto error;
 
-   memset(global_map, ' ', (w_adj + 1) * h_adj);
-   for (i = 0; i  omap_dmm-lut_height; i++) {
-   map[i] = global_map + i * (w_adj + 1);
-   map[i][w_adj] = 0

[PATCH v2] drm/omap: Fix usage of IS_ERR_OR_NULL and PTR_ERR

2012-11-16 Thread Andy Gross
Return -ENOMEM if dmm_txn_init cannot allocate a refill engine.

v2: Fix typing issue seen with newer compilers

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 5c809c0..59bf438 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -296,7 +296,7 @@ static int fill(struct tcm_area *area, struct page **pages,

txn = dmm_txn_init(omap_dmm, area->tcm);
if (IS_ERR_OR_NULL(txn))
-   return PTR_ERR(-ENOMEM);
+   return -ENOMEM;

tcm_for_each_slice(slice, *area, area_s) {
struct pat_area p_area = {
-- 
1.7.5.4



[PATCH v2] drm/omap: Fix usage of IS_ERR_OR_NULL and PTR_ERR

2012-11-16 Thread Andy Gross
Return -ENOMEM if dmm_txn_init cannot allocate a refill engine.

v2: Fix typing issue seen with newer compilers

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 5c809c0..59bf438 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -296,7 +296,7 @@ static int fill(struct tcm_area *area, struct page **pages,
 
txn = dmm_txn_init(omap_dmm, area-tcm);
if (IS_ERR_OR_NULL(txn))
-   return PTR_ERR(-ENOMEM);
+   return -ENOMEM;
 
tcm_for_each_slice(slice, *area, area_s) {
struct pat_area p_area = {
-- 
1.7.5.4

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


[PATCH v2] drm/omap: Fix usage of IS_ERR_OR_NULL and PTR_ERR

2012-11-14 Thread Andy Gross
Return -ENOMEM if dmm_txn_init cannot allocate a refill engine.

v2: Fix typing issue seen with newer compilers

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 3ae3955..1499521 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -279,7 +279,7 @@ static int fill(struct tcm_area *area, struct page **pages,

txn = dmm_txn_init(omap_dmm, area->tcm);
if (IS_ERR_OR_NULL(txn))
-   return PTR_ERR(txn);
+   return -ENOMEM;

tcm_for_each_slice(slice, *area, area_s) {
struct pat_area p_area = {
-- 
1.7.5.4



[PATCH v2] drm/omap: Fix usage of IS_ERR_OR_NULL and PTR_ERR

2012-11-14 Thread Andy Gross
Return -ENOMEM if dmm_txn_init cannot allocate a refill engine.

v2: Fix typing issue seen with newer compilers

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 3ae3955..1499521 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -279,7 +279,7 @@ static int fill(struct tcm_area *area, struct page **pages,
 
txn = dmm_txn_init(omap_dmm, area-tcm);
if (IS_ERR_OR_NULL(txn))
-   return PTR_ERR(txn);
+   return -ENOMEM;
 
tcm_for_each_slice(slice, *area, area_s) {
struct pat_area p_area = {
-- 
1.7.5.4

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


[PATCH] drm/omap: Fix usage of IS_ERR_OR_NULL and PTR_ERR

2012-11-13 Thread Andy Gross
Return PTR_ERR(-ENOMEM) if dmm_txn_init cannot allocate a
refill engine.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 3ae3955..1a5a7ca 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -279,7 +279,7 @@ static int fill(struct tcm_area *area, struct page **pages,

txn = dmm_txn_init(omap_dmm, area->tcm);
if (IS_ERR_OR_NULL(txn))
-   return PTR_ERR(txn);
+   return PTR_ERR(-ENOMEM);

tcm_for_each_slice(slice, *area, area_s) {
struct pat_area p_area = {
-- 
1.7.5.4



[PATCH] drm/omap: Fix usage of IS_ERR_OR_NULL and PTR_ERR

2012-11-13 Thread Andy Gross
Return PTR_ERR(-ENOMEM) if dmm_txn_init cannot allocate a
refill engine.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 3ae3955..1a5a7ca 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -279,7 +279,7 @@ static int fill(struct tcm_area *area, struct page **pages,
 
txn = dmm_txn_init(omap_dmm, area-tcm);
if (IS_ERR_OR_NULL(txn))
-   return PTR_ERR(txn);
+   return PTR_ERR(-ENOMEM);
 
tcm_for_each_slice(slice, *area, area_s) {
struct pat_area p_area = {
-- 
1.7.5.4

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


[PATCH] drm/omap: Remove cpu_is_omapXXXX usage in DMM

2012-10-17 Thread Andy Gross
Removed usage of the cpu_is_omap in the DMM driver.  This is no
longer necessary as we can key off of the omap_dmm pointer that is
only non-NULL if the device has been probed successfully.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |2 +-
 drivers/staging/omapdrm/omap_dmm_tiler.h |7 +--
 drivers/staging/omapdrm/omap_gem.c   |2 +-
 3 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index e2f1e37..6376e17 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -487,7 +487,7 @@ size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t 
h)
return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
 }

-bool dmm_is_initialized(void)
+bool dmm_is_available(void)
 {
return omap_dmm ? true : false;
 }
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h 
b/drivers/staging/omapdrm/omap_dmm_tiler.h
index 7b1052a..8c1fe5c 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.h
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.h
@@ -94,7 +94,7 @@ uint32_t tiler_stride(enum tiler_fmt fmt);
 size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
 size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
 void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
-bool dmm_is_initialized(void);
+bool dmm_is_available(void);

 extern struct platform_driver omap_dmm_driver;

@@ -126,9 +126,4 @@ static inline bool validfmt(enum tiler_fmt fmt)
}
 }

-static inline int dmm_is_available(void)
-{
-   return cpu_is_omap44xx();
-}
-
 #endif
diff --git a/drivers/staging/omapdrm/omap_gem.c 
b/drivers/staging/omapdrm/omap_gem.c
index b740adc..33faa32 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -1408,7 +1408,7 @@ void omap_gem_init(struct drm_device *dev)
};
int i, j;

-   if (!dmm_is_initialized()) {
+   if (!dmm_is_available()) {
/* DMM only supported on OMAP4 and later, so this isn't fatal */
dev_warn(dev->dev, "DMM not available, disable DMM support\n");
return;
-- 
1.7.5.4



[PATCH] drm/omap: Remove cpu_is_omapXXXX usage in DMM

2012-10-17 Thread Andy Gross
Removed usage of the cpu_is_omap in the DMM driver.  This is no
longer necessary as we can key off of the omap_dmm pointer that is
only non-NULL if the device has been probed successfully.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |2 +-
 drivers/staging/omapdrm/omap_dmm_tiler.h |7 +--
 drivers/staging/omapdrm/omap_gem.c   |2 +-
 3 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index e2f1e37..6376e17 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -487,7 +487,7 @@ size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t 
h)
return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
 }
 
-bool dmm_is_initialized(void)
+bool dmm_is_available(void)
 {
return omap_dmm ? true : false;
 }
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h 
b/drivers/staging/omapdrm/omap_dmm_tiler.h
index 7b1052a..8c1fe5c 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.h
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.h
@@ -94,7 +94,7 @@ uint32_t tiler_stride(enum tiler_fmt fmt);
 size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
 size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
 void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
-bool dmm_is_initialized(void);
+bool dmm_is_available(void);
 
 extern struct platform_driver omap_dmm_driver;
 
@@ -126,9 +126,4 @@ static inline bool validfmt(enum tiler_fmt fmt)
}
 }
 
-static inline int dmm_is_available(void)
-{
-   return cpu_is_omap44xx();
-}
-
 #endif
diff --git a/drivers/staging/omapdrm/omap_gem.c 
b/drivers/staging/omapdrm/omap_gem.c
index b740adc..33faa32 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -1408,7 +1408,7 @@ void omap_gem_init(struct drm_device *dev)
};
int i, j;
 
-   if (!dmm_is_initialized()) {
+   if (!dmm_is_available()) {
/* DMM only supported on OMAP4 and later, so this isn't fatal */
dev_warn(dev-dev, DMM not available, disable DMM support\n);
return;
-- 
1.7.5.4

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


[PATCH] drm/omap: Fix include error during make

2012-10-16 Thread Andy Gross
Fixed include error for drm_mode.h

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_crtc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_crtc.c 
b/drivers/staging/omapdrm/omap_crtc.c
index 732f2ad..5249223 100644
--- a/drivers/staging/omapdrm/omap_crtc.c
+++ b/drivers/staging/omapdrm/omap_crtc.c
@@ -19,7 +19,7 @@

 #include "omap_drv.h"

-#include "drm_mode.h"
+#include 
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"

-- 
1.7.5.4



[PATCH] drm/omap: Fix include error during make

2012-10-15 Thread Andy Gross
Fixed include error for drm_mode.h

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_crtc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_crtc.c 
b/drivers/staging/omapdrm/omap_crtc.c
index 732f2ad..5249223 100644
--- a/drivers/staging/omapdrm/omap_crtc.c
+++ b/drivers/staging/omapdrm/omap_crtc.c
@@ -19,7 +19,7 @@
 
 #include omap_drv.h
 
-#include drm_mode.h
+#include drm/drm_mode.h
 #include drm_crtc.h
 #include drm_crtc_helper.h
 
-- 
1.7.5.4

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


[PATCH v2] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross
During asynchronous refills, we don't wait for the refill to
finish.  However, we cannot release the engine back to the idle
list until it has actually completed the refill operation.  The
engine release will now be done in the IRQ handler, but only
for asynchronous refill operations.

Synchronous refills will continue to release the engine after they
unblock from waiting on the refill.

v2: Fixed review comments on async variable and bool type

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 ++-
 drivers/staging/omapdrm/omap_dmm_tiler.c |   76 -
 2 files changed, 56 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 09ebc50..273ec12 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,6 +141,8 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;

+   bool async;
+
wait_queue_head_t wait_for_refill;

struct list_head idle_node;
@@ -158,10 +160,11 @@ struct dmm {
dma_addr_t refill_pa;

/* refill engines */
-   struct semaphore engine_sem;
+   wait_queue_head_t engine_queue;
struct list_head idle_head;
struct refill_engine *engines;
int num_engines;
+   atomic_t engine_counter;

/* container information */
int container_width;
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index fda9efc..62d5123 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -29,7 +29,6 @@
 #include 
 #include 
 #include 
-#include 

 #include "omap_dmm_tiler.h"
 #include "omap_dmm_priv.h"
@@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
 }

+static void release_engine(struct refill_engine *engine)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(_lock, flags);
+   list_add(>idle_node, _dmm->idle_head);
+   spin_unlock_irqrestore(_lock, flags);
+
+   atomic_inc(_dmm->engine_counter);
+   wake_up_interruptible(_dmm->engine_queue);
+}
+
 static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 {
struct dmm *dmm = arg;
@@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
writel(status, dmm->base + DMM_PAT_IRQSTATUS);

for (i = 0; i < dmm->num_engines; i++) {
-   if (status & DMM_IRQSTAT_LST)
+   if (status & DMM_IRQSTAT_LST) {
wake_up_interruptible(>engines[i].wait_for_refill);

+   if (dmm->engines[i].async)
+   release_engine(>engines[i]);
+   }
+
status >>= 8;
}

@@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
struct tcm *tcm)
 {
struct dmm_txn *txn = NULL;
struct refill_engine *engine = NULL;
+   int ret;
+   unsigned long flags;

-   down(>engine_sem);
+
+   /* wait until an engine is available */
+   ret = wait_event_interruptible(omap_dmm->engine_queue,
+   atomic_add_unless(_dmm->engine_counter, -1, 0));
+   if (ret)
+   return ERR_PTR(ret);

/* grab an idle engine */
-   spin_lock(_lock);
+   spin_lock_irqsave(_lock, flags);
if (!list_empty(>idle_head)) {
engine = list_entry(dmm->idle_head.next, struct refill_engine,
idle_node);
list_del(>idle_node);
}
-   spin_unlock(_lock);
+   spin_unlock_irqrestore(_lock, flags);

BUG_ON(!engine);

@@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct 
tcm *tcm)
  * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
  * corresponding slot is cleared (ie. dummy_pa is programmed)
  */
-static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
 {
dma_addr_t pat_pa = 0;
@@ -208,7 +230,7 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,

txn->last_pat = pat;

-   return 0;
+   return;
 }

 /**
@@ -238,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
goto cleanup;
}

+   /* mark whether it is async to denote list management in IRQ handler */
+   engine->async = wait ? false : true;
+
/* kick reload */
writel(engine->refill_pa,
dmm->base + reg[PAT_DESCR][engine->id]);
@@ -252,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
}

 clean

[PATCH] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross
Please disregard this mail.  Wrong patch sent

On 10/12/2012 10:56 AM, Andy Gross wrote:
> During asynchronous refills, we don't wait for the refill to
> finish.  However, we cannot release the engine back to the idle
> list until it has actually completed the refill operation.  The
> engine release will now be done in the IRQ handler, but only
> for asynchronous refill operations.
>
> Synchronous refills will continue to release the engine after they
> unblock from waiting on the refill.
>
> Signed-off-by: Andy Gross 
> ---
>   drivers/staging/omapdrm/omap_dmm_priv.h  |5 ++-
>   drivers/staging/omapdrm/omap_dmm_tiler.c |   77 
> -
>   2 files changed, 57 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
> b/drivers/staging/omapdrm/omap_dmm_priv.h
> index 09ebc50..5ea73305 100644
> --- a/drivers/staging/omapdrm/omap_dmm_priv.h
> +++ b/drivers/staging/omapdrm/omap_dmm_priv.h
> @@ -141,6 +141,8 @@ struct refill_engine {
>   /* only one trans per engine for now */
>   struct dmm_txn txn;
>   
> + unsigned int async;
> +
>   wait_queue_head_t wait_for_refill;
>   
>   struct list_head idle_node;
> @@ -158,10 +160,11 @@ struct dmm {
>   dma_addr_t refill_pa;
>   
>   /* refill engines */
> - struct semaphore engine_sem;
> + wait_queue_head_t engine_queue;
>   struct list_head idle_head;
>   struct refill_engine *engines;
>   int num_engines;
> + atomic_t engine_counter;
>   
>   /* container information */
>   int container_width;
> diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
> b/drivers/staging/omapdrm/omap_dmm_tiler.c
> index fda9efc..eda2fce 100644
> --- a/drivers/staging/omapdrm/omap_dmm_tiler.c
> +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
> @@ -29,7 +29,6 @@
>   #include 
>   #include 
>   #include 
> -#include 
>   
>   #include "omap_dmm_tiler.h"
>   #include "omap_dmm_priv.h"
> @@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, 
> uint32_t wait_mask)
>   return 0;
>   }
>   
> +static void release_engine(struct refill_engine *engine)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(_lock, flags);
> + list_add(>idle_node, _dmm->idle_head);
> + spin_unlock_irqrestore(_lock, flags);
> +
> + atomic_inc(_dmm->engine_counter);
> + wake_up_interruptible(_dmm->engine_queue);
> +}
> +
>   static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
>   {
>   struct dmm *dmm = arg;
> @@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void 
> *arg)
>   writel(status, dmm->base + DMM_PAT_IRQSTATUS);
>   
>   for (i = 0; i < dmm->num_engines; i++) {
> - if (status & DMM_IRQSTAT_LST)
> + if (status & DMM_IRQSTAT_LST) {
>   wake_up_interruptible(>engines[i].wait_for_refill);
>   
> + if (>engines[i].async)
> + release_engine(>engines[i]);
> + }
> +
>   status >>= 8;
>   }
>   
> @@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
> struct tcm *tcm)
>   {
>   struct dmm_txn *txn = NULL;
>   struct refill_engine *engine = NULL;
> + int ret;
> + unsigned long flags;
> +
>   
> - down(>engine_sem);
> + /* wait until an engine is available */
> + ret = wait_event_interruptible(omap_dmm->engine_queue,
> + atomic_add_unless(_dmm->engine_counter, -1, 0));
> + if (ret)
> + return ERR_PTR(ret);
>   
>   /* grab an idle engine */
> - spin_lock(_lock);
> + spin_lock_irqsave(_lock, flags);
>   if (!list_empty(>idle_head)) {
>   engine = list_entry(dmm->idle_head.next, struct refill_engine,
>   idle_node);
>   list_del(>idle_node);
>   }
> - spin_unlock(_lock);
> + spin_unlock_irqrestore(_lock, flags);
>   
>   BUG_ON(!engine);
>   
> @@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
> struct tcm *tcm)
>* Add region to DMM transaction.  If pages or pages[i] is NULL, then the
>* corresponding slot is cleared (ie. dummy_pa is programmed)
>*/
> -static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
> +static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
>   struct page **pages, uint32_t npages, uint32_t roll)
>   {
>   dma_addr_t pat_pa = 0;
> @@ -208,7 +2

[PATCH] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross
During asynchronous refills, we don't wait for the refill to
finish.  However, we cannot release the engine back to the idle
list until it has actually completed the refill operation.  The
engine release will now be done in the IRQ handler, but only
for asynchronous refill operations.

Synchronous refills will continue to release the engine after they
unblock from waiting on the refill.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 ++-
 drivers/staging/omapdrm/omap_dmm_tiler.c |   77 -
 2 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 09ebc50..5ea73305 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,6 +141,8 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;

+   unsigned int async;
+
wait_queue_head_t wait_for_refill;

struct list_head idle_node;
@@ -158,10 +160,11 @@ struct dmm {
dma_addr_t refill_pa;

/* refill engines */
-   struct semaphore engine_sem;
+   wait_queue_head_t engine_queue;
struct list_head idle_head;
struct refill_engine *engines;
int num_engines;
+   atomic_t engine_counter;

/* container information */
int container_width;
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index fda9efc..eda2fce 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -29,7 +29,6 @@
 #include 
 #include 
 #include 
-#include 

 #include "omap_dmm_tiler.h"
 #include "omap_dmm_priv.h"
@@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
 }

+static void release_engine(struct refill_engine *engine)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(_lock, flags);
+   list_add(>idle_node, _dmm->idle_head);
+   spin_unlock_irqrestore(_lock, flags);
+
+   atomic_inc(_dmm->engine_counter);
+   wake_up_interruptible(_dmm->engine_queue);
+}
+
 static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 {
struct dmm *dmm = arg;
@@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
writel(status, dmm->base + DMM_PAT_IRQSTATUS);

for (i = 0; i < dmm->num_engines; i++) {
-   if (status & DMM_IRQSTAT_LST)
+   if (status & DMM_IRQSTAT_LST) {
wake_up_interruptible(>engines[i].wait_for_refill);

+   if (>engines[i].async)
+   release_engine(>engines[i]);
+   }
+
status >>= 8;
}

@@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
struct tcm *tcm)
 {
struct dmm_txn *txn = NULL;
struct refill_engine *engine = NULL;
+   int ret;
+   unsigned long flags;
+

-   down(>engine_sem);
+   /* wait until an engine is available */
+   ret = wait_event_interruptible(omap_dmm->engine_queue,
+   atomic_add_unless(_dmm->engine_counter, -1, 0));
+   if (ret)
+   return ERR_PTR(ret);

/* grab an idle engine */
-   spin_lock(_lock);
+   spin_lock_irqsave(_lock, flags);
if (!list_empty(>idle_head)) {
engine = list_entry(dmm->idle_head.next, struct refill_engine,
idle_node);
list_del(>idle_node);
}
-   spin_unlock(_lock);
+   spin_unlock_irqrestore(_lock, flags);

BUG_ON(!engine);

@@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct 
tcm *tcm)
  * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
  * corresponding slot is cleared (ie. dummy_pa is programmed)
  */
-static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
 {
dma_addr_t pat_pa = 0;
@@ -208,7 +230,7 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,

txn->last_pat = pat;

-   return 0;
+   return;
 }

 /**
@@ -238,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
goto cleanup;
}

+   /* mark whether it is async to denote list management in IRQ handler */
+   engine->async = wait ? 0 : 1;
+
/* kick reload */
writel(engine->refill_pa,
dmm->base + reg[PAT_DESCR][engine->id]);
@@ -252,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
}

 cleanup:
-   spin_lock(_lock);
-   list_add(>idle_nod

[PATCH] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross
On 10/12/2012 08:44 AM, Rob Clark wrote:
>
> US);
>
>  for (i = 0; i < dmm->num_engines; i++) {
> -   if (status & DMM_IRQSTAT_LST)
> +   if (status & DMM_IRQSTAT_LST) {
>  
> wake_up_interruptible(>engines[i].wait_for_refill);
>
> +   if (>engines[i].async)
> Are you sure about that & ?  That looks like a typo, rather than what you 
> want..

Good catch.  I'll fix that, retest, and resubmit.




[PATCH] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross
During asynchronous refills, we don't wait for the refill to
finish.  However, we cannot release the engine back to the idle
list until it has actually completed the refill operation.  The
engine release will now be done in the IRQ handler, but only
for asynchronous refill operations.

Synchronous refills will continue to release the engine after they
unblock from waiting on the refill.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 ++-
 drivers/staging/omapdrm/omap_dmm_tiler.c |   77 -
 2 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 09ebc50..5ea73305 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,6 +141,8 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;

+   unsigned int async;
+
wait_queue_head_t wait_for_refill;

struct list_head idle_node;
@@ -158,10 +160,11 @@ struct dmm {
dma_addr_t refill_pa;

/* refill engines */
-   struct semaphore engine_sem;
+   wait_queue_head_t engine_queue;
struct list_head idle_head;
struct refill_engine *engines;
int num_engines;
+   atomic_t engine_counter;

/* container information */
int container_width;
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 7c19c5c..2fc9218 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -29,7 +29,6 @@
 #include 
 #include 
 #include 
-#include 

 #include "omap_dmm_tiler.h"
 #include "omap_dmm_priv.h"
@@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
 }

+static void release_engine(struct refill_engine *engine)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(_lock, flags);
+   list_add(>idle_node, _dmm->idle_head);
+   spin_unlock_irqrestore(_lock, flags);
+
+   atomic_inc(_dmm->engine_counter);
+   wake_up_interruptible(_dmm->engine_queue);
+}
+
 static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 {
struct dmm *dmm = arg;
@@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
writel(status, dmm->base + DMM_PAT_IRQSTATUS);

for (i = 0; i < dmm->num_engines; i++) {
-   if (status & DMM_IRQSTAT_LST)
+   if (status & DMM_IRQSTAT_LST) {
wake_up_interruptible(>engines[i].wait_for_refill);

+   if (>engines[i].async)
+   release_engine(>engines[i]);
+   }
+
status >>= 8;
}

@@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
struct tcm *tcm)
 {
struct dmm_txn *txn = NULL;
struct refill_engine *engine = NULL;
+   int ret;
+   unsigned long flags;
+

-   down(>engine_sem);
+   /* wait until an engine is available */
+   ret = wait_event_interruptible(omap_dmm->engine_queue,
+   atomic_add_unless(_dmm->engine_counter, -1, 0));
+   if (ret)
+   return ERR_PTR(ret);

/* grab an idle engine */
-   spin_lock(_lock);
+   spin_lock_irqsave(_lock, flags);
if (!list_empty(>idle_head)) {
engine = list_entry(dmm->idle_head.next, struct refill_engine,
idle_node);
list_del(>idle_node);
}
-   spin_unlock(_lock);
+   spin_unlock_irqrestore(_lock, flags);

BUG_ON(!engine);

@@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct 
tcm *tcm)
  * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
  * corresponding slot is cleared (ie. dummy_pa is programmed)
  */
-static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
 {
dma_addr_t pat_pa = 0;
@@ -208,7 +230,7 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,

txn->last_pat = pat;

-   return 0;
+   return;
 }

 /**
@@ -238,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
goto cleanup;
}

+   /* mark whether it is async to denote list management in IRQ handler */
+   engine->async = wait ? 0 : 1;
+
/* kick reload */
writel(engine->refill_pa,
dmm->base + reg[PAT_DESCR][engine->id]);
@@ -252,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
}

 cleanup:
-   spin_lock(_lock);
-   list_add(>idle_nod

[PATCH] drm/omap: Use writecombine for descriptors

2012-10-12 Thread Andy Gross
Use writecombine for descriptor and PAT programming memory.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index fda9efc..7c19c5c 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -525,7 +525,7 @@ static int omap_dmm_remove(struct platform_device *dev)

kfree(omap_dmm->engines);
if (omap_dmm->refill_va)
-   dma_free_coherent(omap_dmm->dev,
+   dma_free_writecombine(omap_dmm->dev,
REFILL_BUFFER_SIZE * omap_dmm->num_engines,
omap_dmm->refill_va,
omap_dmm->refill_pa);
@@ -633,7 +633,7 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm->dummy_pa = page_to_phys(omap_dmm->dummy_page);

/* alloc refill memory */
-   omap_dmm->refill_va = dma_alloc_coherent(>dev,
+   omap_dmm->refill_va = dma_alloc_writecombine(>dev,
REFILL_BUFFER_SIZE * omap_dmm->num_engines,
_dmm->refill_pa, GFP_KERNEL);
if (!omap_dmm->refill_va) {
-- 
1.7.5.4



[PATCH] drm/omap: Remove shadow lut usage

2012-10-12 Thread Andy Gross
Removing extraneous shadow lut maintenance.  There is no need for
this to be in place until power management is added to the driver,
and this extra copy degrades performance for no gain.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |6 --
 drivers/staging/omapdrm/omap_dmm_tiler.c |   24 +---
 2 files changed, 1 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 08b22e9..09ebc50 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,9 +141,6 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;

-   /* offset to lut associated with container */
-   u32 *lut_offset;
-
wait_queue_head_t wait_for_refill;

struct list_head idle_node;
@@ -176,9 +173,6 @@ struct dmm {
/* array of LUT - TCM containers */
struct tcm **tcm;

-   /* LUT table storage */
-   u32 *lut;
-
/* allocation list and lock */
struct list_head alloc_head;
 };
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 3ae3955..fda9efc 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -184,9 +184,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
int columns = (1 + area->x1 - area->x0);
int rows = (1 + area->y1 - area->y0);
int i = columns*rows;
-   u32 *lut = omap_dmm->lut + (engine->tcm->lut_id * omap_dmm->lut_width *
-   omap_dmm->lut_height) +
-   (area->y0 * omap_dmm->lut_width) + area->x0;

pat = alloc_dma(txn, sizeof(struct pat), _pa);

@@ -209,10 +206,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
page_to_phys(pages[n]) : engine->dmm->dummy_pa;
}

-   /* fill in lut with new addresses */
-   for (i = 0; i < rows; i++, lut += omap_dmm->lut_width)
-   memcpy(lut, [i*columns], columns * sizeof(u32));
-
txn->last_pat = pat;

return 0;
@@ -539,8 +532,6 @@ static int omap_dmm_remove(struct platform_device *dev)
if (omap_dmm->dummy_page)
__free_page(omap_dmm->dummy_page);

-   vfree(omap_dmm->lut);
-
if (omap_dmm->irq > 0)
free_irq(omap_dmm->irq, omap_dmm);

@@ -556,7 +547,7 @@ static int omap_dmm_probe(struct platform_device *dev)
 {
int ret = -EFAULT, i;
struct tcm_area area = {0};
-   u32 hwinfo, pat_geom, lut_table_size;
+   u32 hwinfo, pat_geom;
struct resource *mem;

omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL);
@@ -628,16 +619,6 @@ static int omap_dmm_probe(struct platform_device *dev)
 */
writel(0x7e7e7e7e, omap_dmm->base + DMM_PAT_IRQENABLE_SET);

-   lut_table_size = omap_dmm->lut_width * omap_dmm->lut_height *
-   omap_dmm->num_lut;
-
-   omap_dmm->lut = vmalloc(lut_table_size * sizeof(*omap_dmm->lut));
-   if (!omap_dmm->lut) {
-   dev_err(>dev, "could not allocate lut table\n");
-   ret = -ENOMEM;
-   goto fail;
-   }
-
omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32);
if (!omap_dmm->dummy_page) {
dev_err(>dev, "could not allocate dummy page\n");
@@ -720,9 +701,6 @@ static int omap_dmm_probe(struct platform_device *dev)
.p1.y = omap_dmm->container_height - 1,
};

-   for (i = 0; i < lut_table_size; i++)
-   omap_dmm->lut[i] = omap_dmm->dummy_pa;
-
/* initialize all LUTs to dummy page entries */
for (i = 0; i < omap_dmm->num_lut; i++) {
area.tcm = omap_dmm->tcm[i];
-- 
1.7.5.4



Re: [PATCH] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross

On 10/12/2012 08:44 AM, Rob Clark wrote:


US);

 for (i = 0; i  dmm-num_engines; i++) {
-   if (status  DMM_IRQSTAT_LST)
+   if (status  DMM_IRQSTAT_LST) {
 
wake_up_interruptible(dmm-engines[i].wait_for_refill);

+   if (dmm-engines[i].async)
Are you sure about that  ?  That looks like a typo, rather than what you want..


Good catch.  I'll fix that, retest, and resubmit.


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


[PATCH] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross
During asynchronous refills, we don't wait for the refill to
finish.  However, we cannot release the engine back to the idle
list until it has actually completed the refill operation.  The
engine release will now be done in the IRQ handler, but only
for asynchronous refill operations.

Synchronous refills will continue to release the engine after they
unblock from waiting on the refill.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 ++-
 drivers/staging/omapdrm/omap_dmm_tiler.c |   77 -
 2 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 09ebc50..5ea73305 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,6 +141,8 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;
 
+   unsigned int async;
+
wait_queue_head_t wait_for_refill;
 
struct list_head idle_node;
@@ -158,10 +160,11 @@ struct dmm {
dma_addr_t refill_pa;
 
/* refill engines */
-   struct semaphore engine_sem;
+   wait_queue_head_t engine_queue;
struct list_head idle_head;
struct refill_engine *engines;
int num_engines;
+   atomic_t engine_counter;
 
/* container information */
int container_width;
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index fda9efc..eda2fce 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -29,7 +29,6 @@
 #include linux/mm.h
 #include linux/time.h
 #include linux/list.h
-#include linux/semaphore.h
 
 #include omap_dmm_tiler.h
 #include omap_dmm_priv.h
@@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
 }
 
+static void release_engine(struct refill_engine *engine)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(list_lock, flags);
+   list_add(engine-idle_node, omap_dmm-idle_head);
+   spin_unlock_irqrestore(list_lock, flags);
+
+   atomic_inc(omap_dmm-engine_counter);
+   wake_up_interruptible(omap_dmm-engine_queue);
+}
+
 static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 {
struct dmm *dmm = arg;
@@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
writel(status, dmm-base + DMM_PAT_IRQSTATUS);
 
for (i = 0; i  dmm-num_engines; i++) {
-   if (status  DMM_IRQSTAT_LST)
+   if (status  DMM_IRQSTAT_LST) {
wake_up_interruptible(dmm-engines[i].wait_for_refill);
 
+   if (dmm-engines[i].async)
+   release_engine(dmm-engines[i]);
+   }
+
status = 8;
}
 
@@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
struct tcm *tcm)
 {
struct dmm_txn *txn = NULL;
struct refill_engine *engine = NULL;
+   int ret;
+   unsigned long flags;
+
 
-   down(dmm-engine_sem);
+   /* wait until an engine is available */
+   ret = wait_event_interruptible(omap_dmm-engine_queue,
+   atomic_add_unless(omap_dmm-engine_counter, -1, 0));
+   if (ret)
+   return ERR_PTR(ret);
 
/* grab an idle engine */
-   spin_lock(list_lock);
+   spin_lock_irqsave(list_lock, flags);
if (!list_empty(dmm-idle_head)) {
engine = list_entry(dmm-idle_head.next, struct refill_engine,
idle_node);
list_del(engine-idle_node);
}
-   spin_unlock(list_lock);
+   spin_unlock_irqrestore(list_lock, flags);
 
BUG_ON(!engine);
 
@@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct 
tcm *tcm)
  * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
  * corresponding slot is cleared (ie. dummy_pa is programmed)
  */
-static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
 {
dma_addr_t pat_pa = 0;
@@ -208,7 +230,7 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
 
txn-last_pat = pat;
 
-   return 0;
+   return;
 }
 
 /**
@@ -238,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
goto cleanup;
}
 
+   /* mark whether it is async to denote list management in IRQ handler */
+   engine-async = wait ? 0 : 1;
+
/* kick reload */
writel(engine-refill_pa,
dmm-base + reg[PAT_DESCR][engine-id]);
@@ -252,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
}
 
 cleanup:
-   spin_lock(list_lock

Re: [PATCH] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross

Please disregard this mail.  Wrong patch sent

On 10/12/2012 10:56 AM, Andy Gross wrote:

During asynchronous refills, we don't wait for the refill to
finish.  However, we cannot release the engine back to the idle
list until it has actually completed the refill operation.  The
engine release will now be done in the IRQ handler, but only
for asynchronous refill operations.

Synchronous refills will continue to release the engine after they
unblock from waiting on the refill.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
  drivers/staging/omapdrm/omap_dmm_priv.h  |5 ++-
  drivers/staging/omapdrm/omap_dmm_tiler.c |   77 -
  2 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 09ebc50..5ea73305 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,6 +141,8 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;
  
+	unsigned int async;

+
wait_queue_head_t wait_for_refill;
  
  	struct list_head idle_node;

@@ -158,10 +160,11 @@ struct dmm {
dma_addr_t refill_pa;
  
  	/* refill engines */

-   struct semaphore engine_sem;
+   wait_queue_head_t engine_queue;
struct list_head idle_head;
struct refill_engine *engines;
int num_engines;
+   atomic_t engine_counter;
  
  	/* container information */

int container_width;
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index fda9efc..eda2fce 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -29,7 +29,6 @@
  #include linux/mm.h
  #include linux/time.h
  #include linux/list.h
-#include linux/semaphore.h
  
  #include omap_dmm_tiler.h

  #include omap_dmm_priv.h
@@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
  }
  
+static void release_engine(struct refill_engine *engine)

+{
+   unsigned long flags;
+
+   spin_lock_irqsave(list_lock, flags);
+   list_add(engine-idle_node, omap_dmm-idle_head);
+   spin_unlock_irqrestore(list_lock, flags);
+
+   atomic_inc(omap_dmm-engine_counter);
+   wake_up_interruptible(omap_dmm-engine_queue);
+}
+
  static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
  {
struct dmm *dmm = arg;
@@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
writel(status, dmm-base + DMM_PAT_IRQSTATUS);
  
  	for (i = 0; i  dmm-num_engines; i++) {

-   if (status  DMM_IRQSTAT_LST)
+   if (status  DMM_IRQSTAT_LST) {
wake_up_interruptible(dmm-engines[i].wait_for_refill);
  
+			if (dmm-engines[i].async)

+   release_engine(dmm-engines[i]);
+   }
+
status = 8;
}
  
@@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)

  {
struct dmm_txn *txn = NULL;
struct refill_engine *engine = NULL;
+   int ret;
+   unsigned long flags;
+
  
-	down(dmm-engine_sem);

+   /* wait until an engine is available */
+   ret = wait_event_interruptible(omap_dmm-engine_queue,
+   atomic_add_unless(omap_dmm-engine_counter, -1, 0));
+   if (ret)
+   return ERR_PTR(ret);
  
  	/* grab an idle engine */

-   spin_lock(list_lock);
+   spin_lock_irqsave(list_lock, flags);
if (!list_empty(dmm-idle_head)) {
engine = list_entry(dmm-idle_head.next, struct refill_engine,
idle_node);
list_del(engine-idle_node);
}
-   spin_unlock(list_lock);
+   spin_unlock_irqrestore(list_lock, flags);
  
  	BUG_ON(!engine);
  
@@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)

   * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
   * corresponding slot is cleared (ie. dummy_pa is programmed)
   */
-static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
  {
dma_addr_t pat_pa = 0;
@@ -208,7 +230,7 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
  
  	txn-last_pat = pat;
  
-	return 0;

+   return;
  }
  
  /**

@@ -238,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
goto cleanup;
}
  
+	/* mark whether it is async to denote list management in IRQ handler */

+   engine-async = wait ? 0 : 1;
+
/* kick reload */
writel(engine-refill_pa,
dmm-base + reg[PAT_DESCR][engine-id]);
@@ -252,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn

[PATCH v2] drm/omap: Fix release of refill engine

2012-10-12 Thread Andy Gross
During asynchronous refills, we don't wait for the refill to
finish.  However, we cannot release the engine back to the idle
list until it has actually completed the refill operation.  The
engine release will now be done in the IRQ handler, but only
for asynchronous refill operations.

Synchronous refills will continue to release the engine after they
unblock from waiting on the refill.

v2: Fixed review comments on async variable and bool type

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 ++-
 drivers/staging/omapdrm/omap_dmm_tiler.c |   76 -
 2 files changed, 56 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 09ebc50..273ec12 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,6 +141,8 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;
 
+   bool async;
+
wait_queue_head_t wait_for_refill;
 
struct list_head idle_node;
@@ -158,10 +160,11 @@ struct dmm {
dma_addr_t refill_pa;
 
/* refill engines */
-   struct semaphore engine_sem;
+   wait_queue_head_t engine_queue;
struct list_head idle_head;
struct refill_engine *engines;
int num_engines;
+   atomic_t engine_counter;
 
/* container information */
int container_width;
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index fda9efc..62d5123 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -29,7 +29,6 @@
 #include linux/mm.h
 #include linux/time.h
 #include linux/list.h
-#include linux/semaphore.h
 
 #include omap_dmm_tiler.h
 #include omap_dmm_priv.h
@@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
 }
 
+static void release_engine(struct refill_engine *engine)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(list_lock, flags);
+   list_add(engine-idle_node, omap_dmm-idle_head);
+   spin_unlock_irqrestore(list_lock, flags);
+
+   atomic_inc(omap_dmm-engine_counter);
+   wake_up_interruptible(omap_dmm-engine_queue);
+}
+
 static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 {
struct dmm *dmm = arg;
@@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
writel(status, dmm-base + DMM_PAT_IRQSTATUS);
 
for (i = 0; i  dmm-num_engines; i++) {
-   if (status  DMM_IRQSTAT_LST)
+   if (status  DMM_IRQSTAT_LST) {
wake_up_interruptible(dmm-engines[i].wait_for_refill);
 
+   if (dmm-engines[i].async)
+   release_engine(dmm-engines[i]);
+   }
+
status = 8;
}
 
@@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
struct tcm *tcm)
 {
struct dmm_txn *txn = NULL;
struct refill_engine *engine = NULL;
+   int ret;
+   unsigned long flags;
 
-   down(dmm-engine_sem);
+
+   /* wait until an engine is available */
+   ret = wait_event_interruptible(omap_dmm-engine_queue,
+   atomic_add_unless(omap_dmm-engine_counter, -1, 0));
+   if (ret)
+   return ERR_PTR(ret);
 
/* grab an idle engine */
-   spin_lock(list_lock);
+   spin_lock_irqsave(list_lock, flags);
if (!list_empty(dmm-idle_head)) {
engine = list_entry(dmm-idle_head.next, struct refill_engine,
idle_node);
list_del(engine-idle_node);
}
-   spin_unlock(list_lock);
+   spin_unlock_irqrestore(list_lock, flags);
 
BUG_ON(!engine);
 
@@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct 
tcm *tcm)
  * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
  * corresponding slot is cleared (ie. dummy_pa is programmed)
  */
-static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
 {
dma_addr_t pat_pa = 0;
@@ -208,7 +230,7 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
 
txn-last_pat = pat;
 
-   return 0;
+   return;
 }
 
 /**
@@ -238,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
goto cleanup;
}
 
+   /* mark whether it is async to denote list management in IRQ handler */
+   engine-async = wait ? false : true;
+
/* kick reload */
writel(engine-refill_pa,
dmm-base + reg[PAT_DESCR][engine-id]);
@@ -252,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool

[PATCH] drm/omap: Use writecombine for descriptors

2012-10-11 Thread Andy Gross
Use writecombine for descriptor and PAT programming memory.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index fda9efc..7c19c5c 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -525,7 +525,7 @@ static int omap_dmm_remove(struct platform_device *dev)
 
kfree(omap_dmm-engines);
if (omap_dmm-refill_va)
-   dma_free_coherent(omap_dmm-dev,
+   dma_free_writecombine(omap_dmm-dev,
REFILL_BUFFER_SIZE * omap_dmm-num_engines,
omap_dmm-refill_va,
omap_dmm-refill_pa);
@@ -633,7 +633,7 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm-dummy_pa = page_to_phys(omap_dmm-dummy_page);
 
/* alloc refill memory */
-   omap_dmm-refill_va = dma_alloc_coherent(dev-dev,
+   omap_dmm-refill_va = dma_alloc_writecombine(dev-dev,
REFILL_BUFFER_SIZE * omap_dmm-num_engines,
omap_dmm-refill_pa, GFP_KERNEL);
if (!omap_dmm-refill_va) {
-- 
1.7.5.4

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


[PATCH] drm/omap: Remove shadow lut usage

2012-10-11 Thread Andy Gross
Removing extraneous shadow lut maintenance.  There is no need for
this to be in place until power management is added to the driver,
and this extra copy degrades performance for no gain.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |6 --
 drivers/staging/omapdrm/omap_dmm_tiler.c |   24 +---
 2 files changed, 1 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 08b22e9..09ebc50 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,9 +141,6 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;
 
-   /* offset to lut associated with container */
-   u32 *lut_offset;
-
wait_queue_head_t wait_for_refill;
 
struct list_head idle_node;
@@ -176,9 +173,6 @@ struct dmm {
/* array of LUT - TCM containers */
struct tcm **tcm;
 
-   /* LUT table storage */
-   u32 *lut;
-
/* allocation list and lock */
struct list_head alloc_head;
 };
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 3ae3955..fda9efc 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -184,9 +184,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
int columns = (1 + area-x1 - area-x0);
int rows = (1 + area-y1 - area-y0);
int i = columns*rows;
-   u32 *lut = omap_dmm-lut + (engine-tcm-lut_id * omap_dmm-lut_width *
-   omap_dmm-lut_height) +
-   (area-y0 * omap_dmm-lut_width) + area-x0;
 
pat = alloc_dma(txn, sizeof(struct pat), pat_pa);
 
@@ -209,10 +206,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
page_to_phys(pages[n]) : engine-dmm-dummy_pa;
}
 
-   /* fill in lut with new addresses */
-   for (i = 0; i  rows; i++, lut += omap_dmm-lut_width)
-   memcpy(lut, data[i*columns], columns * sizeof(u32));
-
txn-last_pat = pat;
 
return 0;
@@ -539,8 +532,6 @@ static int omap_dmm_remove(struct platform_device *dev)
if (omap_dmm-dummy_page)
__free_page(omap_dmm-dummy_page);
 
-   vfree(omap_dmm-lut);
-
if (omap_dmm-irq  0)
free_irq(omap_dmm-irq, omap_dmm);
 
@@ -556,7 +547,7 @@ static int omap_dmm_probe(struct platform_device *dev)
 {
int ret = -EFAULT, i;
struct tcm_area area = {0};
-   u32 hwinfo, pat_geom, lut_table_size;
+   u32 hwinfo, pat_geom;
struct resource *mem;
 
omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL);
@@ -628,16 +619,6 @@ static int omap_dmm_probe(struct platform_device *dev)
 */
writel(0x7e7e7e7e, omap_dmm-base + DMM_PAT_IRQENABLE_SET);
 
-   lut_table_size = omap_dmm-lut_width * omap_dmm-lut_height *
-   omap_dmm-num_lut;
-
-   omap_dmm-lut = vmalloc(lut_table_size * sizeof(*omap_dmm-lut));
-   if (!omap_dmm-lut) {
-   dev_err(dev-dev, could not allocate lut table\n);
-   ret = -ENOMEM;
-   goto fail;
-   }
-
omap_dmm-dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32);
if (!omap_dmm-dummy_page) {
dev_err(dev-dev, could not allocate dummy page\n);
@@ -720,9 +701,6 @@ static int omap_dmm_probe(struct platform_device *dev)
.p1.y = omap_dmm-container_height - 1,
};
 
-   for (i = 0; i  lut_table_size; i++)
-   omap_dmm-lut[i] = omap_dmm-dummy_pa;
-
/* initialize all LUTs to dummy page entries */
for (i = 0; i  omap_dmm-num_lut; i++) {
area.tcm = omap_dmm-tcm[i];
-- 
1.7.5.4

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


[PATCH] drm/omap: Fix release of refill engine

2012-10-11 Thread Andy Gross
During asynchronous refills, we don't wait for the refill to
finish.  However, we cannot release the engine back to the idle
list until it has actually completed the refill operation.  The
engine release will now be done in the IRQ handler, but only
for asynchronous refill operations.

Synchronous refills will continue to release the engine after they
unblock from waiting on the refill.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |5 ++-
 drivers/staging/omapdrm/omap_dmm_tiler.c |   77 -
 2 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 09ebc50..5ea73305 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,6 +141,8 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;
 
+   unsigned int async;
+
wait_queue_head_t wait_for_refill;
 
struct list_head idle_node;
@@ -158,10 +160,11 @@ struct dmm {
dma_addr_t refill_pa;
 
/* refill engines */
-   struct semaphore engine_sem;
+   wait_queue_head_t engine_queue;
struct list_head idle_head;
struct refill_engine *engines;
int num_engines;
+   atomic_t engine_counter;
 
/* container information */
int container_width;
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 7c19c5c..2fc9218 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -29,7 +29,6 @@
 #include linux/mm.h
 #include linux/time.h
 #include linux/list.h
-#include linux/semaphore.h
 
 #include omap_dmm_tiler.h
 #include omap_dmm_priv.h
@@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
 }
 
+static void release_engine(struct refill_engine *engine)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(list_lock, flags);
+   list_add(engine-idle_node, omap_dmm-idle_head);
+   spin_unlock_irqrestore(list_lock, flags);
+
+   atomic_inc(omap_dmm-engine_counter);
+   wake_up_interruptible(omap_dmm-engine_queue);
+}
+
 static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 {
struct dmm *dmm = arg;
@@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
writel(status, dmm-base + DMM_PAT_IRQSTATUS);
 
for (i = 0; i  dmm-num_engines; i++) {
-   if (status  DMM_IRQSTAT_LST)
+   if (status  DMM_IRQSTAT_LST) {
wake_up_interruptible(dmm-engines[i].wait_for_refill);
 
+   if (dmm-engines[i].async)
+   release_engine(dmm-engines[i]);
+   }
+
status = 8;
}
 
@@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
struct tcm *tcm)
 {
struct dmm_txn *txn = NULL;
struct refill_engine *engine = NULL;
+   int ret;
+   unsigned long flags;
+
 
-   down(dmm-engine_sem);
+   /* wait until an engine is available */
+   ret = wait_event_interruptible(omap_dmm-engine_queue,
+   atomic_add_unless(omap_dmm-engine_counter, -1, 0));
+   if (ret)
+   return ERR_PTR(ret);
 
/* grab an idle engine */
-   spin_lock(list_lock);
+   spin_lock_irqsave(list_lock, flags);
if (!list_empty(dmm-idle_head)) {
engine = list_entry(dmm-idle_head.next, struct refill_engine,
idle_node);
list_del(engine-idle_node);
}
-   spin_unlock(list_lock);
+   spin_unlock_irqrestore(list_lock, flags);
 
BUG_ON(!engine);
 
@@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct 
tcm *tcm)
  * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
  * corresponding slot is cleared (ie. dummy_pa is programmed)
  */
-static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
 {
dma_addr_t pat_pa = 0;
@@ -208,7 +230,7 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
 
txn-last_pat = pat;
 
-   return 0;
+   return;
 }
 
 /**
@@ -238,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
goto cleanup;
}
 
+   /* mark whether it is async to denote list management in IRQ handler */
+   engine-async = wait ? 0 : 1;
+
/* kick reload */
writel(engine-refill_pa,
dmm-base + reg[PAT_DESCR][engine-id]);
@@ -252,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
}
 
 cleanup:
-   spin_lock(list_lock

[PATCH] staging: omapdrm: Fix DMM sparse warnings

2012-08-09 Thread Andy Gross
Fix the following sparse warnings:

drivers/staging/omapdrm/omap_dmm_tiler.c:123:13:
   warning: symbol 'omap_dmm_irq_handler' was not declared.
   Should it be static?

drivers/staging/omapdrm/omap_dmm_tiler.c:370:24:
   warning: Using plain integer as NULL pointer

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 8619783..ec7a5c8 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -120,7 +120,7 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
 }

-irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
+static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 {
struct dmm *dmm = arg;
uint32_t status = readl(dmm->base + DMM_PAT_IRQSTATUS);
@@ -367,7 +367,7 @@ struct tiler_block *tiler_reserve_1d(size_t size)
int num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;

if (!block)
-   return 0;
+   return ERR_PTR(-ENOMEM);

block->fmt = TILFMT_PAGE;

-- 
1.7.5.4



[PATCH] staging: omapdrm: Remove unnecessary memcpy

2012-08-09 Thread Andy Gross
Removed the unnecessary copy of the memory page addresses when
programming the DMM/PAT and all support code for the lut copy.
The original intent was to have this code in place for
suspend/resume functionality w.r.t. DEVICE_OFF.

Performance analysis showed that the extra copy from uncached memory
led to a fairly hefty penalty when programming large 1D or 2D
buffers.  This can be implemented in a more efficient manner when we
actually have to support DEVICE_OFF suspend/resume operations.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |6 --
 drivers/staging/omapdrm/omap_dmm_tiler.c |   25 +
 2 files changed, 1 insertions(+), 30 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 08b22e9..09ebc50 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,9 +141,6 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;

-   /* offset to lut associated with container */
-   u32 *lut_offset;
-
wait_queue_head_t wait_for_refill;

struct list_head idle_node;
@@ -176,9 +173,6 @@ struct dmm {
/* array of LUT - TCM containers */
struct tcm **tcm;

-   /* LUT table storage */
-   u32 *lut;
-
/* allocation list and lock */
struct list_head alloc_head;
 };
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index ec7a5c8..80d3f8a 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -24,7 +24,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -184,9 +183,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
int columns = (1 + area->x1 - area->x0);
int rows = (1 + area->y1 - area->y0);
int i = columns*rows;
-   u32 *lut = omap_dmm->lut + (engine->tcm->lut_id * omap_dmm->lut_width *
-   omap_dmm->lut_height) +
-   (area->y0 * omap_dmm->lut_width) + area->x0;

pat = alloc_dma(txn, sizeof(struct pat), _pa);

@@ -209,10 +205,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct 
pat_area *area,
page_to_phys(pages[n]) : engine->dmm->dummy_pa;
}

-   /* fill in lut with new addresses */
-   for (i = 0; i < rows; i++, lut += omap_dmm->lut_width)
-   memcpy(lut, [i*columns], columns * sizeof(u32));
-
txn->last_pat = pat;

return 0;
@@ -504,8 +496,6 @@ static int omap_dmm_remove(struct platform_device *dev)
if (omap_dmm->dummy_page)
__free_page(omap_dmm->dummy_page);

-   vfree(omap_dmm->lut);
-
if (omap_dmm->irq > 0)
free_irq(omap_dmm->irq, omap_dmm);

@@ -521,7 +511,7 @@ static int omap_dmm_probe(struct platform_device *dev)
 {
int ret = -EFAULT, i;
struct tcm_area area = {0};
-   u32 hwinfo, pat_geom, lut_table_size;
+   u32 hwinfo, pat_geom;
struct resource *mem;

omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL);
@@ -593,16 +583,6 @@ static int omap_dmm_probe(struct platform_device *dev)
 */
writel(0x7e7e7e7e, omap_dmm->base + DMM_PAT_IRQENABLE_SET);

-   lut_table_size = omap_dmm->lut_width * omap_dmm->lut_height *
-   omap_dmm->num_lut;
-
-   omap_dmm->lut = vmalloc(lut_table_size * sizeof(*omap_dmm->lut));
-   if (!omap_dmm->lut) {
-   dev_err(>dev, "could not allocate lut table\n");
-   ret = -ENOMEM;
-   goto fail;
-   }
-
omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32);
if (!omap_dmm->dummy_page) {
dev_err(>dev, "could not allocate dummy page\n");
@@ -685,9 +665,6 @@ static int omap_dmm_probe(struct platform_device *dev)
.p1.y = omap_dmm->container_height - 1,
};

-   for (i = 0; i < lut_table_size; i++)
-   omap_dmm->lut[i] = omap_dmm->dummy_pa;
-
/* initialize all LUTs to dummy page entries */
for (i = 0; i < omap_dmm->num_lut; i++) {
area.tcm = omap_dmm->tcm[i];
-- 
1.7.5.4



[PATCH] staging: omapdrm: Fix DMM sparse warnings

2012-08-08 Thread Andy Gross
Fix the following sparse warnings:

drivers/staging/omapdrm/omap_dmm_tiler.c:123:13:
   warning: symbol 'omap_dmm_irq_handler' was not declared.
   Should it be static?

drivers/staging/omapdrm/omap_dmm_tiler.c:370:24:
   warning: Using plain integer as NULL pointer

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_tiler.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 8619783..ec7a5c8 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -120,7 +120,7 @@ static int wait_status(struct refill_engine *engine, 
uint32_t wait_mask)
return 0;
 }
 
-irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
+static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 {
struct dmm *dmm = arg;
uint32_t status = readl(dmm-base + DMM_PAT_IRQSTATUS);
@@ -367,7 +367,7 @@ struct tiler_block *tiler_reserve_1d(size_t size)
int num_pages = (size + PAGE_SIZE - 1)  PAGE_SHIFT;
 
if (!block)
-   return 0;
+   return ERR_PTR(-ENOMEM);
 
block-fmt = TILFMT_PAGE;
 
-- 
1.7.5.4

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


[PATCH] staging: omapdrm: fix crash when freeing bad fb

2012-05-24 Thread Andy Gross
During unload, don't cleanup the framebuffer if it is not valid.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_fbdev.c |   10 +++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_fbdev.c 
b/drivers/staging/omapdrm/omap_fbdev.c
index 11acd4c..8c6ed3b 100644
--- a/drivers/staging/omapdrm/omap_fbdev.c
+++ b/drivers/staging/omapdrm/omap_fbdev.c
@@ -208,7 +208,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
 */
ret = omap_gem_get_paddr(fbdev->bo, , true);
if (ret) {
-   dev_err(dev->dev, "could not map (paddr)!\n");
+   dev_err(dev->dev,
+   "could not map (paddr)!  Skipping framebuffer alloc\n");
ret = -ENOMEM;
goto fail;
}
@@ -388,8 +389,11 @@ void omap_fbdev_free(struct drm_device *dev)

fbi = helper->fbdev;

-   unregister_framebuffer(fbi);
-   framebuffer_release(fbi);
+   /* only cleanup framebuffer if it is present */
+   if (fbi) {
+   unregister_framebuffer(fbi);
+   framebuffer_release(fbi);
+   }

drm_fb_helper_fini(helper);

-- 
1.7.5.4



[PATCH] staging: omapdrm: Fix error paths during dmm init

2012-05-24 Thread Andy Gross
Failures during the dmm probe can cause the kernel to crash.  Moved
the spinlock to a global and moved list initializations immediately
after the allocation of the dmm private structure.

Signed-off-by: Andy Gross 
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |1 -
 drivers/staging/omapdrm/omap_dmm_tiler.c |   44 -
 2 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 2f529ab..08b22e9 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -181,7 +181,6 @@ struct dmm {

/* allocation list and lock */
struct list_head alloc_head;
-   spinlock_t list_lock;
 };

 #endif
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 1ecb6a7..3bc715d 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -40,6 +40,9 @@
 static struct tcm *containers[TILFMT_NFORMATS];
 static struct dmm *omap_dmm;

+/* global spinlock for protecting lists */
+static DEFINE_SPINLOCK(list_lock);
+
 /* Geometry table */
 #define GEOM(xshift, yshift, bytes_per_pixel) { \
.x_shft = (xshift), \
@@ -147,13 +150,13 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
struct tcm *tcm)
down(>engine_sem);

/* grab an idle engine */
-   spin_lock(>list_lock);
+   spin_lock(_lock);
if (!list_empty(>idle_head)) {
engine = list_entry(dmm->idle_head.next, struct refill_engine,
idle_node);
list_del(>idle_node);
}
-   spin_unlock(>list_lock);
+   spin_unlock(_lock);

BUG_ON(!engine);

@@ -256,9 +259,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
}

 cleanup:
-   spin_lock(>list_lock);
+   spin_lock(_lock);
list_add(>idle_node, >idle_head);
-   spin_unlock(>list_lock);
+   spin_unlock(_lock);

up(_dmm->engine_sem);
return ret;
@@ -351,9 +354,9 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, 
uint16_t w,
}

/* add to allocation list */
-   spin_lock(_dmm->list_lock);
+   spin_lock(_lock);
list_add(>alloc_node, _dmm->alloc_head);
-   spin_unlock(_dmm->list_lock);
+   spin_unlock(_lock);

return block;
 }
@@ -374,9 +377,9 @@ struct tiler_block *tiler_reserve_1d(size_t size)
return 0;
}

-   spin_lock(_dmm->list_lock);
+   spin_lock(_lock);
list_add(>alloc_node, _dmm->alloc_head);
-   spin_unlock(_dmm->list_lock);
+   spin_unlock(_lock);

return block;
 }
@@ -389,9 +392,9 @@ int tiler_release(struct tiler_block *block)
if (block->area.tcm)
dev_err(omap_dmm->dev, "failed to release block\n");

-   spin_lock(_dmm->list_lock);
+   spin_lock(_lock);
list_del(>alloc_node);
-   spin_unlock(_dmm->list_lock);
+   spin_unlock(_lock);

kfree(block);
return ret;
@@ -479,13 +482,13 @@ static int omap_dmm_remove(struct platform_device *dev)

if (omap_dmm) {
/* free all area regions */
-   spin_lock(_dmm->list_lock);
+   spin_lock(_lock);
list_for_each_entry_safe(block, _block, _dmm->alloc_head,
alloc_node) {
list_del(>alloc_node);
kfree(block);
}
-   spin_unlock(_dmm->list_lock);
+   spin_unlock(_lock);

for (i = 0; i < omap_dmm->num_lut; i++)
if (omap_dmm->tcm && omap_dmm->tcm[i])
@@ -503,7 +506,7 @@ static int omap_dmm_remove(struct platform_device *dev)

vfree(omap_dmm->lut);

-   if (omap_dmm->irq != -1)
+   if (omap_dmm->irq > 0)
free_irq(omap_dmm->irq, omap_dmm);

iounmap(omap_dmm->base);
@@ -527,6 +530,10 @@ static int omap_dmm_probe(struct platform_device *dev)
goto fail;
}

+   /* initialize lists */
+   INIT_LIST_HEAD(_dmm->alloc_head);
+   INIT_LIST_HEAD(_dmm->idle_head);
+
/* lookup hwmod data - base address and irq */
mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!mem) {
@@ -629,7 +636,6 @@ static int omap_dmm_probe(struct platform_device *dev)
}

sema_init(_dmm->engine_sem, omap_dmm->num_engines);
-   INIT_LIST_HEAD(_dmm->idle_head);
for (i = 0; i < omap_dmm->num_engines; i++) {
omap_dmm->engines[i].id = i;
omap_dmm->engines[i].dmm = omap_dmm;
@@ -672,9 +678,6 @@ static int omap_dmm_prob

[PATCH] staging: omapdrm: Fix error paths during dmm init

2012-05-24 Thread Andy Gross
Failures during the dmm probe can cause the kernel to crash.  Moved
the spinlock to a global and moved list initializations immediately
after the allocation of the dmm private structure.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 drivers/staging/omapdrm/omap_dmm_priv.h  |1 -
 drivers/staging/omapdrm/omap_dmm_tiler.c |   44 -
 2 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h 
b/drivers/staging/omapdrm/omap_dmm_priv.h
index 2f529ab..08b22e9 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -181,7 +181,6 @@ struct dmm {
 
/* allocation list and lock */
struct list_head alloc_head;
-   spinlock_t list_lock;
 };
 
 #endif
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c 
b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 1ecb6a7..3bc715d 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -40,6 +40,9 @@
 static struct tcm *containers[TILFMT_NFORMATS];
 static struct dmm *omap_dmm;
 
+/* global spinlock for protecting lists */
+static DEFINE_SPINLOCK(list_lock);
+
 /* Geometry table */
 #define GEOM(xshift, yshift, bytes_per_pixel) { \
.x_shft = (xshift), \
@@ -147,13 +150,13 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, 
struct tcm *tcm)
down(dmm-engine_sem);
 
/* grab an idle engine */
-   spin_lock(dmm-list_lock);
+   spin_lock(list_lock);
if (!list_empty(dmm-idle_head)) {
engine = list_entry(dmm-idle_head.next, struct refill_engine,
idle_node);
list_del(engine-idle_node);
}
-   spin_unlock(dmm-list_lock);
+   spin_unlock(list_lock);
 
BUG_ON(!engine);
 
@@ -256,9 +259,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
}
 
 cleanup:
-   spin_lock(dmm-list_lock);
+   spin_lock(list_lock);
list_add(engine-idle_node, dmm-idle_head);
-   spin_unlock(dmm-list_lock);
+   spin_unlock(list_lock);
 
up(omap_dmm-engine_sem);
return ret;
@@ -351,9 +354,9 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, 
uint16_t w,
}
 
/* add to allocation list */
-   spin_lock(omap_dmm-list_lock);
+   spin_lock(list_lock);
list_add(block-alloc_node, omap_dmm-alloc_head);
-   spin_unlock(omap_dmm-list_lock);
+   spin_unlock(list_lock);
 
return block;
 }
@@ -374,9 +377,9 @@ struct tiler_block *tiler_reserve_1d(size_t size)
return 0;
}
 
-   spin_lock(omap_dmm-list_lock);
+   spin_lock(list_lock);
list_add(block-alloc_node, omap_dmm-alloc_head);
-   spin_unlock(omap_dmm-list_lock);
+   spin_unlock(list_lock);
 
return block;
 }
@@ -389,9 +392,9 @@ int tiler_release(struct tiler_block *block)
if (block-area.tcm)
dev_err(omap_dmm-dev, failed to release block\n);
 
-   spin_lock(omap_dmm-list_lock);
+   spin_lock(list_lock);
list_del(block-alloc_node);
-   spin_unlock(omap_dmm-list_lock);
+   spin_unlock(list_lock);
 
kfree(block);
return ret;
@@ -479,13 +482,13 @@ static int omap_dmm_remove(struct platform_device *dev)
 
if (omap_dmm) {
/* free all area regions */
-   spin_lock(omap_dmm-list_lock);
+   spin_lock(list_lock);
list_for_each_entry_safe(block, _block, omap_dmm-alloc_head,
alloc_node) {
list_del(block-alloc_node);
kfree(block);
}
-   spin_unlock(omap_dmm-list_lock);
+   spin_unlock(list_lock);
 
for (i = 0; i  omap_dmm-num_lut; i++)
if (omap_dmm-tcm  omap_dmm-tcm[i])
@@ -503,7 +506,7 @@ static int omap_dmm_remove(struct platform_device *dev)
 
vfree(omap_dmm-lut);
 
-   if (omap_dmm-irq != -1)
+   if (omap_dmm-irq  0)
free_irq(omap_dmm-irq, omap_dmm);
 
iounmap(omap_dmm-base);
@@ -527,6 +530,10 @@ static int omap_dmm_probe(struct platform_device *dev)
goto fail;
}
 
+   /* initialize lists */
+   INIT_LIST_HEAD(omap_dmm-alloc_head);
+   INIT_LIST_HEAD(omap_dmm-idle_head);
+
/* lookup hwmod data - base address and irq */
mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!mem) {
@@ -629,7 +636,6 @@ static int omap_dmm_probe(struct platform_device *dev)
}
 
sema_init(omap_dmm-engine_sem, omap_dmm-num_engines);
-   INIT_LIST_HEAD(omap_dmm-idle_head);
for (i = 0; i  omap_dmm-num_engines; i++) {
omap_dmm-engines[i].id = i;
omap_dmm-engines[i].dmm = omap_dmm;
@@ -672,9 +678,6 @@ static int

[PATCH] omap2+: add drm device

2012-05-23 Thread Andy Gross
Register OMAP DRM/KMS platform device.  DMM is split into a
separate device using hwmod.

Signed-off-by: Andy Gross 
---
 arch/arm/mach-omap2/Makefile   |4 ++
 arch/arm/mach-omap2/drm.c  |   61 
 drivers/staging/omapdrm/omap_drv.h |2 +-
 drivers/staging/omapdrm/omap_priv.h|   55 
 include/linux/platform_data/omap_drm.h |   52 +++
 5 files changed, 118 insertions(+), 56 deletions(-)
 create mode 100644 arch/arm/mach-omap2/drm.c
 delete mode 100644 drivers/staging/omapdrm/omap_priv.h
 create mode 100644 include/linux/platform_data/omap_drm.h

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 49f92bc..c301ab7 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -187,6 +187,10 @@ ifneq ($(CONFIG_TIDSPBRIDGE),)
 obj-y  += dsp.o
 endif

+ifneq ($(CONFIG_DRM_OMAP),)
+obj-y  += drm.o
+endif
+
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)+= board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
new file mode 100644
index 000..72e0f01b
--- /dev/null
+++ b/arch/arm/mach-omap2/drm.c
@@ -0,0 +1,61 @@
+/*
+ * DRM/KMS device registration for TI OMAP platforms
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE)
+
+static struct platform_device omap_drm_device = {
+   .dev = {
+   .coherent_dma_mask = DMA_BIT_MASK(32),
+   },
+   .name = "omapdrm",
+   .id = 0,
+};
+
+static int __init omap_init_drm(void)
+{
+   struct omap_hwmod *oh = NULL;
+   struct platform_device *pdev;
+
+   /* lookup and populate the DMM information, if present - OMAP4+ */
+   oh = omap_hwmod_lookup("dmm");
+
+   if (oh) {
+   pdev = omap_device_build(oh->name, -1, oh, NULL, 0, NULL, 0,
+   false);
+   WARN(IS_ERR(pdev), "Could not build omap_device for %s\n",
+   oh->name);
+   }
+
+   return platform_device_register(_drm_device);
+
+}
+
+arch_initcall(omap_init_drm);
+
+#endif
diff --git a/drivers/staging/omapdrm/omap_drv.h 
b/drivers/staging/omapdrm/omap_drv.h
index b7e0f07..96296e0 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -25,8 +25,8 @@
 #include 
 #include 
 #include 
+#include 
 #include "omap_drm.h"
-#include "omap_priv.h"

 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt, ##__VA_ARGS__) /* verbose debug */
diff --git a/drivers/staging/omapdrm/omap_priv.h 
b/drivers/staging/omapdrm/omap_priv.h
deleted file mode 100644
index ef64414..000
--- a/drivers/staging/omapdrm/omap_priv.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * include/drm/omap_priv.h
- *
- * Copyright (C) 2011 Texas Instruments
- * Author: Rob Clark 
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __OMAP_PRIV_H__
-#define __OMAP_PRIV_H__
-
-/* Non-userspace facing APIs
- */
-
-/* optional platform data to configure the default configuration of which
- * pipes/overlays/CRTCs are used.. if this is not provided, then instead the
- * first CONFIG_DRM_OMAP_NUM_CRTCS are used, and they are each connected to
- * one manager, with priority given to managers that are connected to
- * detected devices.  Remaining overlays are used as video planes.  This
- * should be a good default behavior for most cases, but yet there 

[PATCH] omap2+: add drm device

2012-05-23 Thread Andy Gross
Register OMAP DRM/KMS platform device.  DMM is split into a
separate device using hwmod.

Signed-off-by: Andy Gross andy.gr...@ti.com
---
 arch/arm/mach-omap2/Makefile   |4 ++
 arch/arm/mach-omap2/drm.c  |   61 
 drivers/staging/omapdrm/omap_drv.h |2 +-
 drivers/staging/omapdrm/omap_priv.h|   55 
 include/linux/platform_data/omap_drm.h |   52 +++
 5 files changed, 118 insertions(+), 56 deletions(-)
 create mode 100644 arch/arm/mach-omap2/drm.c
 delete mode 100644 drivers/staging/omapdrm/omap_priv.h
 create mode 100644 include/linux/platform_data/omap_drm.h

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 49f92bc..c301ab7 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -187,6 +187,10 @@ ifneq ($(CONFIG_TIDSPBRIDGE),)
 obj-y  += dsp.o
 endif
 
+ifneq ($(CONFIG_DRM_OMAP),)
+obj-y  += drm.o
+endif
+
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)+= board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
new file mode 100644
index 000..72e0f01b
--- /dev/null
+++ b/arch/arm/mach-omap2/drm.c
@@ -0,0 +1,61 @@
+/*
+ * DRM/KMS device registration for TI OMAP platforms
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark rob.cl...@linaro.org
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/mm.h
+#include linux/init.h
+#include linux/platform_device.h
+#include linux/dma-mapping.h
+
+#include plat/omap_device.h
+#include plat/omap_hwmod.h
+
+#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE)
+
+static struct platform_device omap_drm_device = {
+   .dev = {
+   .coherent_dma_mask = DMA_BIT_MASK(32),
+   },
+   .name = omapdrm,
+   .id = 0,
+};
+
+static int __init omap_init_drm(void)
+{
+   struct omap_hwmod *oh = NULL;
+   struct platform_device *pdev;
+
+   /* lookup and populate the DMM information, if present - OMAP4+ */
+   oh = omap_hwmod_lookup(dmm);
+
+   if (oh) {
+   pdev = omap_device_build(oh-name, -1, oh, NULL, 0, NULL, 0,
+   false);
+   WARN(IS_ERR(pdev), Could not build omap_device for %s\n,
+   oh-name);
+   }
+
+   return platform_device_register(omap_drm_device);
+
+}
+
+arch_initcall(omap_init_drm);
+
+#endif
diff --git a/drivers/staging/omapdrm/omap_drv.h 
b/drivers/staging/omapdrm/omap_drv.h
index b7e0f07..96296e0 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -25,8 +25,8 @@
 #include linux/types.h
 #include drm/drmP.h
 #include drm/drm_crtc_helper.h
+#include linux/platform_data/omap_drm.h
 #include omap_drm.h
-#include omap_priv.h
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt\n, ##__VA_ARGS__)
 #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt, ##__VA_ARGS__) /* verbose debug */
diff --git a/drivers/staging/omapdrm/omap_priv.h 
b/drivers/staging/omapdrm/omap_priv.h
deleted file mode 100644
index ef64414..000
--- a/drivers/staging/omapdrm/omap_priv.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * include/drm/omap_priv.h
- *
- * Copyright (C) 2011 Texas Instruments
- * Author: Rob Clark r...@ti.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see http://www.gnu.org/licenses/.
- */
-
-#ifndef __OMAP_PRIV_H__
-#define __OMAP_PRIV_H__
-
-/* Non-userspace facing APIs
- */
-
-/* optional platform data to configure the default configuration of which
- * pipes/overlays/CRTCs are used.. if this is not provided, then instead the
- * first CONFIG_DRM_OMAP_NUM_CRTCS are used, and they are each connected to
- * one manager, with priority given to managers