Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-25 Thread Dave Gerlach
Ohad,

On 09/17/2014 08:37 AM, Ohad Ben-Cohen wrote: Hi Suman,

 On Tue, Sep 16, 2014 at 7:14 PM, Suman Anna s-a...@ti.com wrote:
 The current remoteproc infrastructure automatically calls rproc_boot only
 as part of the rpmsg/virtio stack (in remoteproc_virtio.c), but since the
 WkupM3 does not use rpmsg, there is no automatic booting of the WkupM3
 processor.  This is the reason why rproc_boot is called as part of the
 WkupM3 driver probe sequence. What are your concerns here, and if you think
 this is not the right place do invoke rproc_boot, where do you expect it to
 be called?

 The remoteproc layer is meant to hide hardware-specific details, and allow
 high-level hardware-agnostic code to boot a remote processor, in order to
 achieve some task, without even caring what kind of hardware it is booting.

 So generally we have some consumer driver asking remoteproc to boot a remote
  processor, and in turn, remoteproc asking a hardware-specific vendor driver
  to take care of the hardware details like actually taking the remote
 processor out of reset.

 The consumer driver is some code that deals with some hardware agnostic task.
 Today the only consumer we have is rpmsg, so it's perfectly reasonable if
 remoteproc needs to be adapted a bit to accommodate other consumers as they
 show up.

 Can you think of any component in your code that is not necessarily hardware
  specific, and that one day might be useful for other vendors? Can you
 describe the task you're trying to achieve, the entities involved and the
 flow between them?

 Also do note that, there is no way at present to retrieve the struct rproc
  for a given remote processor, to be able to invoke the rproc_boot from a
 different layer.

 It's perfectly ok to make struct rproc public if we have a consumer that
 requires it.

 Splitting this would still require some kind of notifier from remoteproc
 for the other layers for them to know that the WkupM3 remote processor has
  been loaded and booted successfully. This is also done as part of the
 WkupM3 driver at the moment.

 Are there entities, other than the one that calls rproc_boot, that needs to
 know that the WkupM3 is up? if so, let's discuss who should notify them -
 remoteproc or the actual invoker of rproc_boot. It probably depends on who
 those entities are and what's their relation, if any, to the WkupM3 driver.

There are three layers at play here. The pm layer, the ipc layer, and the rproc
layer. As we know, currently the problem is that the ipc and rproc layer are
combined.

PM on am33xx is ENTIRELY dependent on the wkup_m3. It can't enable any PM OPs
until the FW is ready. So that is one place where the PM layer must be notified.
The other instance is for IPC, the wkup_m3 triggers an interrupt back to the MPU
when it it is done with it's work after an IPC event (explained more later), so
the PM code must be notified of this as well.

Here is the exact flow between PM, IPC, and wkup_m3 during a suspend cycle:

Boot:
*Firmware gets loaded and wkup_m3 has hard reset deasserted and starts executing
(Definite wkup_m3 rproc responsibility).

*PM code is notified that wkup_m3 is awake (currently by wkup_m3_rproc start
hook) and calls into pm code with rproc_ready hook and uses IPC registers (which
were filled by wkup_m3) to check version number and make sure it's compatible.
This sounds like IPC layer responsibility, but does the IPC layer just handle
reading back the registers and give these values for the PM layer to interpret?
Or does it do the interpreting and gives back a specific PM value? (In this case
fw version.)

Suspend:
*PM code tells wkup_m3_rproc driver to place the command for the desired PM
state in the IPC registers along with any other info needed for suspend
(determined by PM code) and then ping the wkup_m3 using the mailbox, which is
just a dummy write, the mailbox is not actually used just the interrupt. Once
this happens the wkup_m3 itself runs, prepares for the desired PM state, and
triggers it's own wkup_m3 interrupt, unrelated to the mailbox interrupt.

*Once this interrupt is sent the wkup_m3_rproc has the irq handler for the
interrupt and calls into pm code using txev_handler hook I defined, and with
this, the PM code proceeds, and the wkup_m3 just waits for MPU clock gate
(unrelated to IPC or wkup_m3, triggered by other SoC functionality).

*On resume, no interrupt is generated from wkup_m3 but the PM code, in the
standard resume path, reads from the IPC registers to check a status value
(without receiving an interrupt like before, just assumes there is data because
a resume is happening, interrupts are disabled still at this point) and then the
PM code interprets the status value and a wake source value and does whatever it
wants with it. This also sounds like IPC layer responsibility but again the
question comes up do we provide generic IPC reg reading functionality or let the
IPC layer do more, like with the version number read?

I am not sure exactly 

Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-17 Thread Ohad Ben-Cohen
Hi Suman,

On Tue, Sep 16, 2014 at 7:14 PM, Suman Anna s-a...@ti.com wrote:
 The current remoteproc infrastructure automatically calls rproc_boot
 only as part of the rpmsg/virtio stack (in remoteproc_virtio.c), but
 since the WkupM3 does not use rpmsg, there is no automatic booting of
 the WkupM3 processor.  This is the reason why rproc_boot is called as
 part of the WkupM3 driver probe sequence. What are your concerns here,
 and if you think this is not the right place do invoke rproc_boot, where
 do you expect it to be called?

The remoteproc layer is meant to hide hardware-specific details, and
allow high-level hardware-agnostic code to boot a remote processor, in
order to achieve some task, without even caring what kind of hardware
it is booting.

So generally we have some consumer driver asking remoteproc to boot a
remote processor, and in turn, remoteproc asking a hardware-specific
vendor driver to take care of the hardware details like actually
taking the remote processor out of reset.

The consumer driver is some code that deals with some hardware
agnostic task. Today the only consumer we have is rpmsg, so it's
perfectly reasonable if remoteproc needs to be adapted a bit to
accommodate other consumers as they show up.

Can you think of any component in your code that is not necessarily
hardware specific, and that one day might be useful for other vendors?
Can you describe the task you're trying to achieve, the entities
involved and the flow between them?

 Also do note that, there is no way
 at present to retrieve the struct rproc for a given remote processor, to
 be able to invoke the rproc_boot from a different layer.

It's perfectly ok to make struct rproc public if we have a consumer
that requires it.

 Splitting this would still require some kind of notifier from remoteproc
 for the other layers for them to know that the WkupM3 remote processor
 has been loaded and booted successfully. This is also done as part of
 the WkupM3 driver at the moment.

Are there entities, other than the one that calls rproc_boot, that
needs to know that the WkupM3 is up? if so, let's discuss who should
notify them - remoteproc or the actual invoker of rproc_boot. It
probably depends on who those entities are and what's their relation,
if any, to the WkupM3 driver.

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


Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-16 Thread Ohad Ben-Cohen
On Wed, Sep 10, 2014 at 12:10 AM, Kevin Hilman khil...@kernel.org wrote:
 What I think you need to do (and what I've recommended at least once in
 earlier reviews) put all the (non-rproc) wkup_m3 IPC into into one
 driver and create a well-described, well-documented API that the
 platform PM code will use.

 IMO, the current split is very difficult to read/understand, which
 means it will even more difficult to maintain.

I strongly agree.

A remoteproc driver should generally only register its
hardware-specific implementation of the rproc_ops via the remoteproc
framework. It is not expected to expose public API of its own - that's
why we have the generic remoteproc layer for. It makes perfect sense
not to use rpmsg for communications if it's not lightweight enough,
but exposing a new set of IPC API should take place in a separate
well-documented driver.

In addition, the suggested remoteproc driver seems to act both as a
low-level hardware-specific driver that plugs into remoteproc (by
registering rproc_ops via the remoteproc framework), and also as a
high-level driver that utilizes the remoteproc public API (by calling
rproc_boot). This alone calls for scrutinizing the design as this is
not very intuitive.

At least for the remoteproc part: if you could provide a simple and
straight-forward remoteproc driver that just implements the rproc_ops,
this could be merged very quickly. The rest of the code most probably
belongs in a different entity, just like Kevin suggested.

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


Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-16 Thread Suman Anna
Hi Ohad,

On 09/16/2014 10:08 AM, Ohad Ben-Cohen wrote:
 On Wed, Sep 10, 2014 at 12:10 AM, Kevin Hilman khil...@kernel.org wrote:
 What I think you need to do (and what I've recommended at least once in
 earlier reviews) put all the (non-rproc) wkup_m3 IPC into into one
 driver and create a well-described, well-documented API that the
 platform PM code will use.

 IMO, the current split is very difficult to read/understand, which
 means it will even more difficult to maintain.
 
 I strongly agree.
 
 A remoteproc driver should generally only register its
 hardware-specific implementation of the rproc_ops via the remoteproc
 framework. It is not expected to expose public API of its own - that's
 why we have the generic remoteproc layer for. It makes perfect sense
 not to use rpmsg for communications if it's not lightweight enough,
 but exposing a new set of IPC API should take place in a separate
 well-documented driver.
 
 In addition, the suggested remoteproc driver seems to act both as a
 low-level hardware-specific driver that plugs into remoteproc (by
 registering rproc_ops via the remoteproc framework), and also as a
 high-level driver that utilizes the remoteproc public API (by calling
 rproc_boot). This alone calls for scrutinizing the design as this is
 not very intuitive.

The current remoteproc infrastructure automatically calls rproc_boot
only as part of the rpmsg/virtio stack (in remoteproc_virtio.c), but
since the WkupM3 does not use rpmsg, there is no automatic booting of
the WkupM3 processor. This is the reason why rproc_boot is called as
part of the WkupM3 driver probe sequence. What are your concerns here,
and if you think this is not the right place do invoke rproc_boot, where
do you expect it to be called? Also do note that, there is no way
at present to retrieve the struct rproc for a given remote processor, to
be able to invoke the rproc_boot from a different layer.

 At least for the remoteproc part: if you could provide a simple and
 straight-forward remoteproc driver that just implements the rproc_ops,
 this could be merged very quickly. The rest of the code most probably
 belongs in a different entity, just like Kevin suggested.
 

Splitting this would still require some kind of notifier from remoteproc
for the other layers for them to know that the WkupM3 remote processor
has been loaded and booted successfully. This is also done as part of
the WkupM3 driver at the moment.

regards
Suman

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


Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-10 Thread Dave Gerlach
Kevin,
On 09/09/2014 04:10 PM, Kevin Hilman wrote:
 Dave Gerlach d-gerl...@ti.com writes:
 
 Kevin/Ohad,
 On 09/09/2014 02:59 PM, Suman Anna wrote:
 Hi Ohad,

 On 09/09/2014 05:31 AM, Ohad Ben-Cohen wrote:
 On Tue, Sep 9, 2014 at 1:30 AM, Kevin Hilman khil...@linaro.org wrote:
 To me, it's not terribly clear how you made the split between this PM
 core code an the remoteproc code.  In the changelog for the remoteproc
 patch, it states it's to load the firmware for and boot the wkup_m3.
 But, while parts of the IPC are here in pm33xx.c, parts of the IPC are
 also inside the remoteproc driver, so I'm quite curious if that's OK
 with the remoteproc maintainers.  Either way, please make it clearer how
 and why you made the split, and please isolate the wkup_m3 IPC/protocol
 from this code.  Think of people wanting to rework/extend the wkup_m3
 firmware.  They shouldn't be messing around in here, but rather inside a
 driver specificaly for the wkup_m3.

 I haven't looked at the code very thoroughly yet, but generally a
 remoteproc driver should only implement the three start/stop/kick
 rproc_ops, and then register them via the remoteproc framework.
 Exposing additional API directly from that driver isn't something we
 immediately want to accept.

 If relevant, we would generally prefer to extend remoteproc instead,
 so other platform-specific drivers could utilize that functionality as
 well. Or rpmsg - if we're missing some IPC functionality.

 The WkupM3 cannot access DDR, and so we don't intend to use rpmsg. The
 IPC with wkup_m3 is usually one of the last steps for putting the SoC
 into a desired low-power state either during suspend or cpuidle, and the
 communication uses a bank of fixed registers. The .kick is specific
 to virtio-based communication, and so this is not gonna be used.

 If you can take a closer look at the wkup_m3 remoteproc driver and give
 your comments, then we can plan on the next steps. Especially as there
 are also pieces pertaining to the PM layer knowing the WkupM3 has been
 loaded and booted. There are already some pending comments on code
 fragments from Santosh and myself, but let us know your inputs on the
 integration aspects on PM, remoteproc and IPC with WkupM3.


 The split was defined by putting all the application specific (to the
 firmware in use) code in the platform pm code while trying to keep all the
 IPC code within the wkup_m3_rproc driver. 
 
 I don't even see that split.  I see the platform PM code directly
 setting IPC register values, but then rproc driver actually sends the
 mailbox command.

Well, really the pm code is setting a structure which gets passed to the
wkup_m3_rproc API and that's what does the write. I suppose the naming of the
structure is misleading though. However, the wkup_m3 driver isn't aware of the
protocol or what is going into these registers for the writes, the PM code
defines the usage.

 
 The exposed API is definitely heavily biased towards the intended
 use-case, 
 
 Maybe if the API was actually documented, it would be easier for us to
 review it.
 
 but the CM3 was designed with this exact purpose in mind and
 not much else, and due to the limited IPC registers we have to work
 with there isn't a whole lot of flexibility. Only IPC reg 0 is always
 used as the resume address, the usage of the other registers is
 defined by the firmware and pm code.

 Just as a refresher for those not familiar with it, the IPC mechanism works
 like this: we load the ipc registers (8 for am33xx, 16 for am43xx) with any
 information we want to communicate to the CM3, 
 
 OK, and this happens currently in the platform PM code, right?
 
 then we make a dummy write to
 the Mailbox which triggers an interrupt on the CM3, the CM3 does what it
 needs to with the info passed in the IPC regs and writes anything it wants to
 communicate back to these registers, and then triggers a different interrupt
 (not related to mailbox) to let the MPU know it is done. 
 
 And this part happens in the rproc driver, right?
 
 It's kind of a mess so I figured one driver was the best way to
 encapsulate it all,
 
 So where is this one driver that encapsulates it all?  


Sp my thinking was that I put the IPC writing in the wkup_m3_rproc driver, but
the actual configuration of what gets written in the PM platform code, to at
least try to keep things generic. Still, I do agree now that the split is not
that clear.

 and I still had to
 introduce callbacks within the wkup_m3_rproc driver so it could let the pm 
 code
 know when the FW loaded (to actually enable pm) and when an interrupt was
 received from the wkup_m3 (so the pm code can process the response).
 
 As Suman stated, this sequence is part of the suspend path and also will be 
 part
 of the lower c-states for cpuidle, so we need something fast and lightweight.
 RPMsg is way more than we need and it doesn't really fit the use case, so I'm
 not sure what makes the most sense, extending remoteproc in some way to 
 

Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-09 Thread Ohad Ben-Cohen
On Tue, Sep 9, 2014 at 1:30 AM, Kevin Hilman khil...@linaro.org wrote:
 To me, it's not terribly clear how you made the split between this PM
 core code an the remoteproc code.  In the changelog for the remoteproc
 patch, it states it's to load the firmware for and boot the wkup_m3.
 But, while parts of the IPC are here in pm33xx.c, parts of the IPC are
 also inside the remoteproc driver, so I'm quite curious if that's OK
 with the remoteproc maintainers.  Either way, please make it clearer how
 and why you made the split, and please isolate the wkup_m3 IPC/protocol
 from this code.  Think of people wanting to rework/extend the wkup_m3
 firmware.  They shouldn't be messing around in here, but rather inside a
 driver specificaly for the wkup_m3.

I haven't looked at the code very thoroughly yet, but generally a
remoteproc driver should only implement the three start/stop/kick
rproc_ops, and then register them via the remoteproc framework.
Exposing additional API directly from that driver isn't something we
immediately want to accept.

If relevant, we would generally prefer to extend remoteproc instead,
so other platform-specific drivers could utilize that functionality as
well. Or rpmsg - if we're missing some IPC functionality.

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


Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-09 Thread Suman Anna
Hi Ohad,

On 09/09/2014 05:31 AM, Ohad Ben-Cohen wrote:
 On Tue, Sep 9, 2014 at 1:30 AM, Kevin Hilman khil...@linaro.org wrote:
 To me, it's not terribly clear how you made the split between this PM
 core code an the remoteproc code.  In the changelog for the remoteproc
 patch, it states it's to load the firmware for and boot the wkup_m3.
 But, while parts of the IPC are here in pm33xx.c, parts of the IPC are
 also inside the remoteproc driver, so I'm quite curious if that's OK
 with the remoteproc maintainers.  Either way, please make it clearer how
 and why you made the split, and please isolate the wkup_m3 IPC/protocol
 from this code.  Think of people wanting to rework/extend the wkup_m3
 firmware.  They shouldn't be messing around in here, but rather inside a
 driver specificaly for the wkup_m3.
 
 I haven't looked at the code very thoroughly yet, but generally a
 remoteproc driver should only implement the three start/stop/kick
 rproc_ops, and then register them via the remoteproc framework.
 Exposing additional API directly from that driver isn't something we
 immediately want to accept.
 
 If relevant, we would generally prefer to extend remoteproc instead,
 so other platform-specific drivers could utilize that functionality as
 well. Or rpmsg - if we're missing some IPC functionality.

The WkupM3 cannot access DDR, and so we don't intend to use rpmsg. The
IPC with wkup_m3 is usually one of the last steps for putting the SoC
into a desired low-power state either during suspend or cpuidle, and the
communication uses a bank of fixed registers. The .kick is specific
to virtio-based communication, and so this is not gonna be used.

If you can take a closer look at the wkup_m3 remoteproc driver and give
your comments, then we can plan on the next steps. Especially as there
are also pieces pertaining to the PM layer knowing the WkupM3 has been
loaded and booted. There are already some pending comments on code
fragments from Santosh and myself, but let us know your inputs on the
integration aspects on PM, remoteproc and IPC with WkupM3.

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


Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-09 Thread Dave Gerlach
Kevin/Ohad,
On 09/09/2014 02:59 PM, Suman Anna wrote:
 Hi Ohad,
 
 On 09/09/2014 05:31 AM, Ohad Ben-Cohen wrote:
 On Tue, Sep 9, 2014 at 1:30 AM, Kevin Hilman khil...@linaro.org wrote:
 To me, it's not terribly clear how you made the split between this PM
 core code an the remoteproc code.  In the changelog for the remoteproc
 patch, it states it's to load the firmware for and boot the wkup_m3.
 But, while parts of the IPC are here in pm33xx.c, parts of the IPC are
 also inside the remoteproc driver, so I'm quite curious if that's OK
 with the remoteproc maintainers.  Either way, please make it clearer how
 and why you made the split, and please isolate the wkup_m3 IPC/protocol
 from this code.  Think of people wanting to rework/extend the wkup_m3
 firmware.  They shouldn't be messing around in here, but rather inside a
 driver specificaly for the wkup_m3.

 I haven't looked at the code very thoroughly yet, but generally a
 remoteproc driver should only implement the three start/stop/kick
 rproc_ops, and then register them via the remoteproc framework.
 Exposing additional API directly from that driver isn't something we
 immediately want to accept.

 If relevant, we would generally prefer to extend remoteproc instead,
 so other platform-specific drivers could utilize that functionality as
 well. Or rpmsg - if we're missing some IPC functionality.
 
 The WkupM3 cannot access DDR, and so we don't intend to use rpmsg. The
 IPC with wkup_m3 is usually one of the last steps for putting the SoC
 into a desired low-power state either during suspend or cpuidle, and the
 communication uses a bank of fixed registers. The .kick is specific
 to virtio-based communication, and so this is not gonna be used.
 
 If you can take a closer look at the wkup_m3 remoteproc driver and give
 your comments, then we can plan on the next steps. Especially as there
 are also pieces pertaining to the PM layer knowing the WkupM3 has been
 loaded and booted. There are already some pending comments on code
 fragments from Santosh and myself, but let us know your inputs on the
 integration aspects on PM, remoteproc and IPC with WkupM3.


The split was defined by putting all the application specific (to the
firmware in use) code in the platform pm code while trying to keep all the
IPC code within the wkup_m3_rproc driver. The exposed API is definitely
heavily biased towards the intended use-case, but the CM3 was designed with
this exact purpose in mind and not much else, and due to the limited IPC
registers we have to work with there isn't a whole lot of flexibility. Only IPC
reg 0 is always used as the resume address, the usage of the other registers is
defined by the firmware and pm code.

Just as a refresher for those not familiar with it, the IPC mechanism works
like this: we load the ipc registers (8 for am33xx, 16 for am43xx) with any
information we want to communicate to the CM3, then we make a dummy write to
the Mailbox which triggers an interrupt on the CM3, the CM3 does what it
needs to with the info passed in the IPC regs and writes anything it wants to
communicate back to these registers, and then triggers a different interrupt
(not related to mailbox) to let the MPU know it is done. It's kind of a mess so
I figured one driver was the best way to encapsulate it all, and I still had to
introduce callbacks within the wkup_m3_rproc driver so it could let the pm code
know when the FW loaded (to actually enable pm) and when an interrupt was
received from the wkup_m3 (so the pm code can process the response).

As Suman stated, this sequence is part of the suspend path and also will be part
of the lower c-states for cpuidle, so we need something fast and lightweight.
RPMsg is way more than we need and it doesn't really fit the use case, so I'm
not sure what makes the most sense, extending remoteproc in some way to support
IPC communication like described above or leaving the basic FW loading
functionality in place in remoteproc but moving the IPC and wkup_m3
functionality back into the platform pm33xx code as it's so specific to that
use-case anyway.

Regards,
Dave

 regards
 Suman
 

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


Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-09 Thread Kevin Hilman
Dave Gerlach d-gerl...@ti.com writes:

 Kevin/Ohad,
 On 09/09/2014 02:59 PM, Suman Anna wrote:
 Hi Ohad,
 
 On 09/09/2014 05:31 AM, Ohad Ben-Cohen wrote:
 On Tue, Sep 9, 2014 at 1:30 AM, Kevin Hilman khil...@linaro.org wrote:
 To me, it's not terribly clear how you made the split between this PM
 core code an the remoteproc code.  In the changelog for the remoteproc
 patch, it states it's to load the firmware for and boot the wkup_m3.
 But, while parts of the IPC are here in pm33xx.c, parts of the IPC are
 also inside the remoteproc driver, so I'm quite curious if that's OK
 with the remoteproc maintainers.  Either way, please make it clearer how
 and why you made the split, and please isolate the wkup_m3 IPC/protocol
 from this code.  Think of people wanting to rework/extend the wkup_m3
 firmware.  They shouldn't be messing around in here, but rather inside a
 driver specificaly for the wkup_m3.

 I haven't looked at the code very thoroughly yet, but generally a
 remoteproc driver should only implement the three start/stop/kick
 rproc_ops, and then register them via the remoteproc framework.
 Exposing additional API directly from that driver isn't something we
 immediately want to accept.

 If relevant, we would generally prefer to extend remoteproc instead,
 so other platform-specific drivers could utilize that functionality as
 well. Or rpmsg - if we're missing some IPC functionality.
 
 The WkupM3 cannot access DDR, and so we don't intend to use rpmsg. The
 IPC with wkup_m3 is usually one of the last steps for putting the SoC
 into a desired low-power state either during suspend or cpuidle, and the
 communication uses a bank of fixed registers. The .kick is specific
 to virtio-based communication, and so this is not gonna be used.
 
 If you can take a closer look at the wkup_m3 remoteproc driver and give
 your comments, then we can plan on the next steps. Especially as there
 are also pieces pertaining to the PM layer knowing the WkupM3 has been
 loaded and booted. There are already some pending comments on code
 fragments from Santosh and myself, but let us know your inputs on the
 integration aspects on PM, remoteproc and IPC with WkupM3.


 The split was defined by putting all the application specific (to the
 firmware in use) code in the platform pm code while trying to keep all the
 IPC code within the wkup_m3_rproc driver. 

I don't even see that split.  I see the platform PM code directly
setting IPC register values, but then rproc driver actually sends the
mailbox command.

 The exposed API is definitely heavily biased towards the intended
 use-case, 

Maybe if the API was actually documented, it would be easier for us to
review it.

 but the CM3 was designed with this exact purpose in mind and
 not much else, and due to the limited IPC registers we have to work
 with there isn't a whole lot of flexibility. Only IPC reg 0 is always
 used as the resume address, the usage of the other registers is
 defined by the firmware and pm code.

 Just as a refresher for those not familiar with it, the IPC mechanism works
 like this: we load the ipc registers (8 for am33xx, 16 for am43xx) with any
 information we want to communicate to the CM3, 

OK, and this happens currently in the platform PM code, right?

 then we make a dummy write to
 the Mailbox which triggers an interrupt on the CM3, the CM3 does what it
 needs to with the info passed in the IPC regs and writes anything it wants to
 communicate back to these registers, and then triggers a different interrupt
 (not related to mailbox) to let the MPU know it is done. 

And this part happens in the rproc driver, right?

 It's kind of a mess so I figured one driver was the best way to
 encapsulate it all,

So where is this one driver that encapsulates it all?  

 and I still had to
 introduce callbacks within the wkup_m3_rproc driver so it could let the pm 
 code
 know when the FW loaded (to actually enable pm) and when an interrupt was
 received from the wkup_m3 (so the pm code can process the response).

 As Suman stated, this sequence is part of the suspend path and also will be 
 part
 of the lower c-states for cpuidle, so we need something fast and lightweight.
 RPMsg is way more than we need and it doesn't really fit the use case, so I'm
 not sure what makes the most sense, extending remoteproc in some way to 
 support
 IPC communication like described above or leaving the basic FW loading
 functionality in place in remoteproc but moving the IPC and wkup_m3
 functionality back into the platform pm33xx code as it's so specific to that
 use-case anyway.

I'm not advocating for using rpmsg (anymore).  But I dont' think shoving
your rpmsg-lite IPC into your rproc driver is the right answer either
(and Ohad's repsonse confirmed my suspicion.)

What I think you need to do (and what I've recommended at least once in
earlier reviews) put all the (non-rproc) wkup_m3 IPC into into one
driver and create a well-described, well-documented API that the

Re: [PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-09-08 Thread Kevin Hilman
+Ohad

Dave Gerlach d-gerl...@ti.com writes:

 AM335x supports various low power modes as documented
 in section 8.1.4.3 of the AM335x Technical Reference Manual.

 DeepSleep0 mode offers the lowest power mode with limited
 wakeup sources without a system reboot and is mapped as
 the suspend state in the kernel. In this state, MPU and
 PER domains are turned off with the internal RAM held in
 retention to facilitate the resume process. As part of
 the boot process, the assembly code is copied over to OCMCRAM
 using the OMAP SRAM code so it can be executed to turn of the
 EMIF.

 AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU
 in DeepSleep0 and Standby entry and exit. WKUP_M3 takes care
 of the clockdomain and powerdomain transitions based on the
 intended low power state. MPU needs to load the appropriate
 WKUP_M3 binary onto the WKUP_M3 memory space before it can
 leverage any of the PM features like DeepSleep.

 The WKUP_M3 is managed by a remoteproc driver. The PM code hooks
 into the remoteproc driver through an rproc_ready callback to
 allow PM features to become available once the firmware for the
 wkup_m3 has been loaded. This code maintains its own state machine
 for the wkup_m3 so that it can be used in the manner intended for
 low power modes.

 In the current implementation when the suspend process
 is initiated, MPU interrupts the WKUP_M3 to let it know about
 the intent of entering DeepSleep0 and waits for an ACK. When
 the ACK is received MPU continues with its suspend process
 to suspend all the drivers and then jumps to assembly in
 OCMC RAM. The assembly code puts the external RAM in self-refresh
 mode, gates the MPU clock, and then finally executes the WFI
 instruction. Execution of the WFI instruction with MPU clock gated
 triggers another interrupt to the WKUP_M3 which then continues
 with the power down sequence wherein the clockdomain and
 powerdomain transition takes place. As part of the sleep sequence,
 WKUP_M3 unmasks the interrupt lines for the wakeup sources. WFI
 execution on WKUP_M3 causes the hardware to disable the main
 oscillator of the SoC and from here system remains in sleep state
 until a wake source brings the system into resume path.

 When a wakeup event occurs, WKUP_M3 starts the power-up
 sequence by switching on the power domains and finally
 enabling the clock to MPU. Since the MPU gets powered down
 as part of the sleep sequence in the resume path ROM code
 starts executing. The ROM code detects a wakeup from sleep
 and then jumps to the resume location in OCMC which was
 populated in one of the IPC registers as part of the suspend
 sequence.

 Code is based on work by Vaibhav Bedia.

 Signed-off-by: Dave Gerlach d-gerl...@ti.com
 ---
 v3-v4:
   Remove all direct wkup_m3 usage and moved to rproc driver introduced
   in previous patch.

This statement is rather confusing as there's still quite a bit of
direct wkup_m3 usage, including the guts of the protocal for message
passing.  I thought you had agreed based on earilier reviews to split
out the wkup_m3 into it's on little driver with a clear/clean API which
could be called from here?

To me, it's not terribly clear how you made the split between this PM
core code an the remoteproc code.  In the changelog for the remoteproc
patch, it states it's to load the firmware for and boot the wkup_m3.
But, while parts of the IPC are here in pm33xx.c, parts of the IPC are
also inside the remoteproc driver, so I'm quite curious if that's OK
with the remoteproc maintainers.  Either way, please make it clearer how
and why you made the split, and please isolate the wkup_m3 IPC/protocol
from this code.  Think of people wanting to rework/extend the wkup_m3
firmware.  They shouldn't be messing around in here, but rather inside a
driver specificaly for the wkup_m3.

Also, I'll beat this drum again even though nobody is listening: it's
still very fuzzy to me how this approach is going to be used to manage
low-power idle?  Is low-power idle just being completely ignored for
this SoC?

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


[PATCH v4 10/11] ARM: OMAP2+: AM33XX: Basic suspend resume support

2014-07-10 Thread Dave Gerlach
AM335x supports various low power modes as documented
in section 8.1.4.3 of the AM335x Technical Reference Manual.

DeepSleep0 mode offers the lowest power mode with limited
wakeup sources without a system reboot and is mapped as
the suspend state in the kernel. In this state, MPU and
PER domains are turned off with the internal RAM held in
retention to facilitate the resume process. As part of
the boot process, the assembly code is copied over to OCMCRAM
using the OMAP SRAM code so it can be executed to turn of the
EMIF.

AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU
in DeepSleep0 and Standby entry and exit. WKUP_M3 takes care
of the clockdomain and powerdomain transitions based on the
intended low power state. MPU needs to load the appropriate
WKUP_M3 binary onto the WKUP_M3 memory space before it can
leverage any of the PM features like DeepSleep.

The WKUP_M3 is managed by a remoteproc driver. The PM code hooks
into the remoteproc driver through an rproc_ready callback to
allow PM features to become available once the firmware for the
wkup_m3 has been loaded. This code maintains its own state machine
for the wkup_m3 so that it can be used in the manner intended for
low power modes.

In the current implementation when the suspend process
is initiated, MPU interrupts the WKUP_M3 to let it know about
the intent of entering DeepSleep0 and waits for an ACK. When
the ACK is received MPU continues with its suspend process
to suspend all the drivers and then jumps to assembly in
OCMC RAM. The assembly code puts the external RAM in self-refresh
mode, gates the MPU clock, and then finally executes the WFI
instruction. Execution of the WFI instruction with MPU clock gated
triggers another interrupt to the WKUP_M3 which then continues
with the power down sequence wherein the clockdomain and
powerdomain transition takes place. As part of the sleep sequence,
WKUP_M3 unmasks the interrupt lines for the wakeup sources. WFI
execution on WKUP_M3 causes the hardware to disable the main
oscillator of the SoC and from here system remains in sleep state
until a wake source brings the system into resume path.

When a wakeup event occurs, WKUP_M3 starts the power-up
sequence by switching on the power domains and finally
enabling the clock to MPU. Since the MPU gets powered down
as part of the sleep sequence in the resume path ROM code
starts executing. The ROM code detects a wakeup from sleep
and then jumps to the resume location in OCMC which was
populated in one of the IPC registers as part of the suspend
sequence.

Code is based on work by Vaibhav Bedia.

Signed-off-by: Dave Gerlach d-gerl...@ti.com
---
v3-v4:
Remove all direct wkup_m3 usage and moved to rproc driver introduced
in previous patch.

 arch/arm/mach-omap2/pm33xx.c | 346 +++
 arch/arm/mach-omap2/pm33xx.h |  64 
 2 files changed, 410 insertions(+)
 create mode 100644 arch/arm/mach-omap2/pm33xx.c
 create mode 100644 arch/arm/mach-omap2/pm33xx.h

diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c
new file mode 100644
index 000..30d0f7d
--- /dev/null
+++ b/arch/arm/mach-omap2/pm33xx.c
@@ -0,0 +1,346 @@
+/*
+ * AM33XX Power Management Routines
+ *
+ * Copyright (C) 2012-2014 Texas Instruments Incorporated - http://www.ti.com/
+ * Vaibhav Bedia, Dave Gerlach
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed as is WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include linux/kernel.h
+#include linux/init.h
+#include linux/cpu.h
+#include linux/err.h
+#include linux/firmware.h
+#include linux/io.h
+#include linux/platform_device.h
+#include linux/sched.h
+#include linux/suspend.h
+#include linux/completion.h
+#include linux/module.h
+#include linux/interrupt.h
+#include linux/ti_emif.h
+#include linux/omap-mailbox.h
+#include linux/sizes.h
+
+#include asm/suspend.h
+#include asm/proc-fns.h
+#include asm/fncpy.h
+#include asm/system_misc.h
+
+#include pm.h
+#include cm33xx.h
+#include pm33xx.h
+#include common.h
+#include clockdomain.h
+#include powerdomain.h
+#include soc.h
+#include sram.h
+
+static void __iomem *am33xx_emif_base;
+static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
+static struct clockdomain *gfx_l4ls_clkdm;
+
+static struct am33xx_pm_context *am33xx_pm;
+
+static DECLARE_COMPLETION(am33xx_pm_sync);
+
+static void (*am33xx_do_wfi_sram)(struct am33xx_suspend_params *);
+
+static struct am33xx_suspend_params susp_params;
+
+#ifdef CONFIG_SUSPEND
+
+static int am33xx_do_sram_idle(long unsigned int unused)
+{
+   am33xx_do_wfi_sram(susp_params);
+   return 0;
+}
+