diff mbox

[RFC] sh: suspend interpreter V1

Message ID 20090323091739.25647.6773.sendpatchset@rx1.opensource.se
State RFC
Headers show

Commit Message

Magnus Damm March 23, 2009, 9:17 a.m. UTC
From: Magnus Damm <damm@igel.co.jp>

Hi Francesco, everyone,

Here comes my first suspend interpreter attempt. This patch
contains a mix of both generic and superh mobile stuff.
It has only been dry coded so it probably is full of bugs.
The main point of interest are probably the SH_PM_OP_xxx ops.

The code in sleep.S is generic, so it should be moved out of
the shmobile directory in the future. The same goes for the
op defines and the structure, and for sh_pm_op(), sh_pm_run(),
sh_pm_init() and sh_pm_cleanup().

Start looking at sh_mobile_pm_setup(). The setup() callback is
used to build the code. The run callback will be used to execute
the built code, but it is unused so far. The old code in sleep.S
is still used, but with a little bit more of hacking it should be
possible to switch over. Not sure what to do about the VBR table
though.

Comments? Shall I keep on adding code, or start a rewrite? =)

Francesco, I suppose you will need more ops?

Signed-off-by: Magnus Damm <damm@igel.co.jp>
---

 arch/sh/kernel/cpu/shmobile/pm.c    |  162 +++++++++++++++++++++++++++++++++++
 arch/sh/kernel/cpu/shmobile/sleep.S |  109 +++++++++++++++++++++++
 2 files changed, 271 insertions(+)

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

Comments

Francesco VIRLINZI March 23, 2009, 3:35 p.m. UTC | #1
Hi Magnus
I think I understood how your system works.

Tell me if I'm wrong...

It seems all your instructions accepts zero of at least one argument and 
all the ' 1: bra 1f'  are used to preload.

The main issue, I see, is that there is no conditional statement possible.

I tryed to build something like:

void while_eq(unsigned long *add, unsigned long mask, unsigned long addr)
{
    for (; ((*add) & mask) != value; );
}

but

sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, _ADDR_);
sh_pm_op(info, SH_PM_OP_AND_IMM_R0,  _MASK_);
sh_pm_op(info, SH_PM_OP_CMP_R0, _VALUE));
sh_pm_op(info, SH_PM_OP_BT, __LABEL__);

On 'SH_PM_OP_CMP_R0' it isn't really a problem... It could be build like 
the other instruction...

While on 'SH_PM_OP_BT' it could be a problem because we don't know the 
'label' address... but I think it
 could be resolved if the sh_pm_op() instead of void returns the address 
of just assembled operation
 therefore I should be able to build something like:

addr = sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, _ADDR_);
sh_pm_op(info, SH_PM_OP_AND_IMM_R0,  _MASK_);
sh_pm_op(info, SH_PM_OP_CMP_R0, _VALUE));
sh_pm_op(info, SH_PM_OP_BT, addr); /* to jump backward... */

Something similar could be done to jump forward... also in this case the 
'jump' should
  be marked in a first phase as incomplete...  and resolved when all the 
code is built.

At least in a first release the jump forward could be not supported.

Let me know if I'm wrong and if do you agree.

Ciao
 Francesco

> From: Magnus Damm <damm@igel.co.jp>
>
> Hi Francesco, everyone,
>
> Here comes my first suspend interpreter attempt. This patch
> contains a mix of both generic and superh mobile stuff.
> It has only been dry coded so it probably is full of bugs.
> The main point of interest are probably the SH_PM_OP_xxx ops.
>
> The code in sleep.S is generic, so it should be moved out of
> the shmobile directory in the future. The same goes for the
> op defines and the structure, and for sh_pm_op(), sh_pm_run(),
> sh_pm_init() and sh_pm_cleanup().
>
> Start looking at sh_mobile_pm_setup(). The setup() callback is
> used to build the code. The run callback will be used to execute
> the built code, but it is unused so far. The old code in sleep.S
> is still used, but with a little bit more of hacking it should be
> possible to switch over. Not sure what to do about the VBR table
> though.
>
> Comments? Shall I keep on adding code, or start a rewrite? =)
>
> Francesco, I suppose you will need more ops?
>
> Signed-off-by: Magnus Damm <damm@igel.co.jp>
> ---
>
>  arch/sh/kernel/cpu/shmobile/pm.c    |  162 +++++++++++++++++++++++++++++++++++
>  arch/sh/kernel/cpu/shmobile/sleep.S |  109 +++++++++++++++++++++++
>  2 files changed, 271 insertions(+)
>
> --- 0001/arch/sh/kernel/cpu/shmobile/pm.c
> +++ work/arch/sh/kernel/cpu/shmobile/pm.c	2009-03-23 18:00:51.000000000 +0900
> @@ -16,6 +16,167 @@
>  #include <asm/suspend.h>
>  #include <asm/uaccess.h>
>  
> +#define SH_PM_OP_IMM_OFFS 8
> +#define SH_PM_OP_JMP_OFFS 12
> +#define SH_PM_OP_SIZE 16
> +
> +#define SH_PM_OP_MOV_IMM_R0	0
> +#define SH_PM_OP_MOV_MEM8_R0	1
> +#define SH_PM_OP_MOV_MEM16_R0	2
> +#define SH_PM_OP_MOV_MEM32_R0	3
> +#define SH_PM_OP_MOV_R0_MEM8	4
> +#define SH_PM_OP_MOV_R0_MEM16	5
> +#define SH_PM_OP_MOV_R0_MEM32	6
> +#define SH_PM_OP_AND_IMM_R0	7
> +#define SH_PM_OP_OR_IMM_R0	8
> +#define SH_PM_OP_ADD_IMM_R0	9
> +#define SH_PM_OP_SLEEP		10
> +#define SH_PM_OP_RTS		11
> +#define SH_PM_OP_NR		12
> +
> +extern unsigned char sh_pm_op_base[SH_PM_OP_SIZE * SH_PM_OP_NR];
> +
> +struct sh_pm_op_info {
> +	unsigned char *buf;
> +	unsigned int nr_ops;
> +	void (*setup)(struct sh_pm_op_info *);
> +	void (*run)(struct sh_pm_op_info *);
> +};
> +
> +static void sh_pm_op(struct sh_pm_op_info *info, int op, unsigned int data)
> +{
> +	unsigned int size = SH_PM_OP_SIZE;
> +	unsigned char *buf = info->buf;
> +
> +	if (buf) {
> +		buf += info->nr_ops * size;
> +		memcpy(buf, &sh_pm_op_base[op * size], size);
> +		*(unsigned int *)(buf + SH_PM_OP_IMM_OFFS) = data;
> +	}
> +	info->nr_ops++;
> +}
> +
> +static void sh_pm_run(struct sh_pm_op_info *info)
> +{
> +	void (*snippet)(void);
> +
> +	/* preload in cache */
> +	snippet = (void *)(info->buf + SH_PM_OP_JMP_OFFS);
> +	snippet();
> +
> +	/* execute in cache */
> +	snippet = (void *)info->buf;
> +	snippet();
> +}
> +
> +int sh_pm_mode_init(struct sh_pm_op_info *info)
> +{
> +	/* run once without buffer to calculate amount of memory needed */
> +	info->buf = NULL;
> +	info->nr_ops = 0;
> +	info->setup(info);
> +
> +	info->buf = kmalloc(info->nr_ops * SH_PM_OP_SIZE, GFP_KERNEL);
> +	if (!info->buf)
> +		return -ENOMEM;
> +
> +	/* run second time with buffer to generate actual code */
> +	info->nr_ops = 0;
> +	info->setup(info);
> +	return 0;
> +}
> +
> +void sh_pm_mode_cleanup(struct sh_pm_op_info *info)
> +{
> +	kfree(info->buf);
> +}
> +
> +/* "sleep" mode */
> +
> +static void sh_mobile_pm_stbcr_setup(struct sh_pm_op_info *info,
> +				     unsigned int mode)
> +{
> +	sh_pm_op(info, SH_PM_OP_MOV_IMM_R0, mode);
> +	sh_pm_op(info, SH_PM_OP_MOV_R0_MEM32, 0xa4150020); /* STBCR */
> +}
> +
> +static void sh_mobile_pm_sleep_setup(struct sh_pm_op_info *info)
> +{
> +	/* make sure STBCR is cleared, execute sleep, return */
> +	sh_mobile_pm_stbcr_setup(info, 0);
> +	sh_pm_op(info, SH_PM_OP_SLEEP, 0);
> +	sh_pm_op(info, SH_PM_OP_RTS, 0);
> +}
> +
> +static struct sh_pm_op_info sh_mobile_pm_sleep = {
> +	.setup = sh_mobile_pm_sleep_setup,
> +	.run = sh_pm_run,
> +};
> +
> +/* "sleep" mode with system memory in self-refresh */
> +
> +static void sh_mobile_pm_sf_suspend(struct sh_pm_op_info *info)
> +{
> +	/* SDRAM: disable power down and put in self-refresh mode */
> +	sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, 0xfe400008); /* SDCR0 */
> +	sh_pm_op(info, SH_PM_OP_OR_IMM_R0, 0x00000400);
> +	sh_pm_op(info, SH_PM_OP_AND_IMM_R0, 0xffff7fff);
> +	sh_pm_op(info, SH_PM_OP_MOV_R0_MEM32, 0xfe400008); /* SDCR0 */
> +}
> +
> +static void sh_mobile_pm_sf_restore(struct sh_pm_op_info *info)
> +{
> +	/* SDRAM: put back in auto-refresh mode */
> +	sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, 0xfe400008); /* SDCR0 */
> +	sh_pm_op(info, SH_PM_OP_AND_IMM_R0, 0xfffffbff);
> +	sh_pm_op(info, SH_PM_OP_MOV_R0_MEM32, 0xfe400008); /* SDCR0 */
> +	sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, 0xfe40001c); /* RTCOR */
> +	sh_pm_op(info, SH_PM_OP_ADD_IMM_R0, (unsigned int)-1);
> +	sh_pm_op(info, SH_PM_OP_OR_IMM_R0, 0xa55a0000);
> +	sh_pm_op(info, SH_PM_OP_MOV_R0_MEM32, 0xfe400018); /* RTCNT */
> +}
> +
> +static void sh_mobile_pm_sleep_sf_setup(struct sh_pm_op_info *info)
> +{
> +	/* setup self-refresh, clear STBCR, execute sleep, restore */
> +	sh_mobile_pm_sf_suspend(info);
> +	sh_mobile_pm_stbcr_setup(info, 0);
> +	sh_pm_op(info, SH_PM_OP_SLEEP, 0);
> +	sh_mobile_pm_sf_restore(info);
> +	sh_pm_op(info, SH_PM_OP_RTS, 0);
> +}
> +
> +static struct sh_pm_op_info sh_mobile_pm_sleep_sf = {
> +	.setup = sh_mobile_pm_sleep_sf_setup,
> +	.run = sh_pm_run,
> +};
> +
> +/* "standby" mode with system memory in self-refresh */
> +
> +static void sh_mobile_pm_standby_sf_setup(struct sh_pm_op_info *info)
> +{
> +	/* setup self-refresh, set STBCR, execute sleep, restore */
> +	sh_mobile_pm_sf_suspend(info);
> +	sh_mobile_pm_stbcr_setup(info, 0x80);
> +	sh_pm_op(info, SH_PM_OP_SLEEP, 0);
> +	sh_mobile_pm_stbcr_setup(info, 0);
> +	sh_mobile_pm_sf_restore(info);
> +	sh_pm_op(info, SH_PM_OP_RTS, 0);
> +}
> +
> +static struct sh_pm_op_info sh_mobile_pm_standby_sf = {
> +	.setup = sh_mobile_pm_standby_sf_setup,
> +	.run = sh_pm_run,
> +};
> +
> +
> +static void sh_mobile_pm_setup(void)
> +{
> +	sh_pm_mode_init(&sh_mobile_pm_sleep);
> +	sh_pm_mode_init(&sh_mobile_pm_sleep_sf);
> +	sh_pm_mode_init(&sh_mobile_pm_standby_sf);
> +}
> +
>  /*
>   * Sleep modes available on SuperH Mobile:
>   *
> @@ -85,6 +246,7 @@ static struct platform_suspend_ops sh_pm
>  
>  static int __init sh_pm_init(void)
>  {
> +	sh_mobile_pm_setup();
>  	suspend_set_ops(&sh_pm_ops);
>  	return 0;
>  }
> --- 0001/arch/sh/kernel/cpu/shmobile/sleep.S
> +++ work/arch/sh/kernel/cpu/shmobile/sleep.S	2009-03-23 17:24:34.000000000 +0900
> @@ -123,3 +123,112 @@ sh_mobile_standby_end:
>  
>  ENTRY(sh_mobile_standby_size)
>  	.long sh_mobile_standby_end - sh_mobile_standby
> +
> +ENTRY(sh_pm_op_base)
> +sh_pm_op_mov_imm_r0:		/* @ SH_PM_OP_MOV_IMM_R0 * SH_PM_OP_SIZE */
> +	mov.l	0f, r0
> +	bra	2f
> +	 nop
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_mov_mem8_r0:		/* @ SH_PM_OP_MOV_MEM8_R0 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 mov.b	@r1, r0
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_mov_mem16_r0:		/* @ SH_PM_OP_MOV_MEM16_R0 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 mov.w	@r1, r0
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_mov_mem32_r0:		/* @ SH_PM_OP_MOV_MEM32_R0 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 mov.l	@r1, r0
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_mov_r0_mem8:		/* @ SH_PM_OP_MOV_R0_MEM8 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 mov.b	r0, @r1
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_mov_r0_mem16:		/* @ SH_PM_OP_MOV_R0_MEM16 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 mov.w	r0, @r1
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_mov_r0_mem32:		/* @ SH_PM_OP_MOV_R0_MEM32 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 mov.l	r0, @r1
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_and_imm_r0:		/* @ SH_PM_OP_AND_IMM_R0 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 and	r1, r0
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_or_imm_r0:		/* @ SH_PM_OP_OR_IMM_R0 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 or	r1, r0
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_add_imm_r0:		/* @ SH_PM_OP_ADD_IMM_R0 * SH_PM_OP_SIZE */
> +2:	mov.l	0f, r1
> +	bra	2f
> +	 add	r1, r0
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_sleep:			/* @ SH_PM_OP_SLEEP * SH_PM_OP_SIZE */
> +2:	sleep
> +	bra	2f
> +	 nop
> +	nop
> +0:	.long	0
> +1:	bra	1f
> +	 nop
> +
> +sh_pm_op_rts:			/* @ SH_PM_OP_RTS * SH_PM_OP_SIZE */
> +2:	rts
> +	 nop
> +	nop
> +	nop
> +0:	.long	0
> +1:	rts
> +	 nop
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>   

--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI March 24, 2009, 7 a.m. UTC | #2
Hi Magnus
> Hi Magnus
> I think I understood how your system works.
>
> Tell me if I'm wrong...
>
> It seems all your instructions accepts zero of at least one argument 
> and all the ' 1: bra 1f'  are used to preload.
>
> The main issue, I see, is that there is no conditional statement 
> possible.
>
> I tryed to build something like:
>
> void while_eq(unsigned long *add, unsigned long mask, unsigned long addr)
> {
>    for (; ((*add) & mask) != value; );
> }
>
> but
>
> sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, _ADDR_);
> sh_pm_op(info, SH_PM_OP_AND_IMM_R0,  _MASK_);
> sh_pm_op(info, SH_PM_OP_CMP_R0, _VALUE));
> sh_pm_op(info, SH_PM_OP_BT, __LABEL__);
>
> On 'SH_PM_OP_CMP_R0' it isn't really a problem... It could be build 
> like the other instruction...
>
> While on 'SH_PM_OP_BT' it could be a problem because we don't know the 
> 'label' address... but I think it
> could be resolved if the sh_pm_op() instead of void returns the 
> address of just assembled operation
> therefore I should be able to build something like:
>
> addr = sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, _ADDR_);
> sh_pm_op(info, SH_PM_OP_AND_IMM_R0,  _MASK_);
> sh_pm_op(info, SH_PM_OP_CMP_R0, _VALUE));
> sh_pm_op(info, SH_PM_OP_BT, addr); /* to jump backward... */
>
> Something similar could be done to jump forward... also in this case 
> the 'jump' should
>  be marked in a first phase as incomplete...  and resolved when all 
> the code is built.
>
> At least in a first release the jump forward could be not supported.
I was thinking that the jump forward could be closed with a function:

void sh_pm_set_data(unsigned long *addr, unsigned long data); /* to set 
the data field in the instruction*/

In this manner
a jump forward could be done with:

jump_addr = sh_pm_op(info, SH_PM_OP_BT, 0); /* to jump forward... zero 
doesn't matter*/
...
...
jump_target = sh_pm_op(info, ....);
sh_pm_set_data(jump_addr, jump_target); /* to set the right data value 
in the previous jump */

In this manner both the jumps are supported.
And with an ADD or a SUB instruction also some delay can be built on top 
of these instructions.
Let me know.
Regards
 Francesco
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Magnus Damm March 24, 2009, 11:08 a.m. UTC | #3
Hi Francesco!

On Tue, Mar 24, 2009 at 4:00 PM, Francesco VIRLINZI
<francesco.virlinzi@st.com> wrote:
> Hi Magnus
>>
>> Hi Magnus
>> I think I understood how your system works.
>>
>> Tell me if I'm wrong...

You seem correct.

>> It seems all your instructions accepts zero of at least one argument and
>> all the ' 1: bra 1f'  are used to preload.
>>
>> The main issue, I see, is that there is no conditional statement possible.

Right, I thought so. Thanks for your input so far.

>> I tryed to build something like:
>>
>> void while_eq(unsigned long *add, unsigned long mask, unsigned long addr)
>> {
>>   for (; ((*add) & mask) != value; );
>> }
>>
>> but
>>
>> sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, _ADDR_);
>> sh_pm_op(info, SH_PM_OP_AND_IMM_R0,  _MASK_);
>> sh_pm_op(info, SH_PM_OP_CMP_R0, _VALUE));
>> sh_pm_op(info, SH_PM_OP_BT, __LABEL__);
>>
>> On 'SH_PM_OP_CMP_R0' it isn't really a problem... It could be build like
>> the other instruction...

Right, no problem. I guess CMP can be ADD together with AND?

>> While on 'SH_PM_OP_BT' it could be a problem because we don't know the
>> 'label' address... but I think it
>> could be resolved if the sh_pm_op() instead of void returns the address of
>> just assembled operation
>> therefore I should be able to build something like:
>>
>> addr = sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, _ADDR_);
>> sh_pm_op(info, SH_PM_OP_AND_IMM_R0,  _MASK_);
>> sh_pm_op(info, SH_PM_OP_CMP_R0, _VALUE));
>> sh_pm_op(info, SH_PM_OP_BT, addr); /* to jump backward... */

Looking good! Simple and efficient!

>> Something similar could be done to jump forward... also in this case the
>> 'jump' should
>>  be marked in a first phase as incomplete...  and resolved when all the
>> code is built.
>>
>> At least in a first release the jump forward could be not supported.
>
> I was thinking that the jump forward could be closed with a function:
>
> void sh_pm_set_data(unsigned long *addr, unsigned long data); /* to set the
> data field in the instruction*/
>
> In this manner
> a jump forward could be done with:
>
> jump_addr = sh_pm_op(info, SH_PM_OP_BT, 0); /* to jump forward... zero
> doesn't matter*/
> ...
> ...
> jump_target = sh_pm_op(info, ....);
> sh_pm_set_data(jump_addr, jump_target); /* to set the right data value in
> the previous jump */
>
> In this manner both the jumps are supported.

Right, I understand. This becomes a bit more complicated but it's not
so strange. As long as the two pass setup() is ok (first pass without
buffer) then I'm ok.

But do we (you!) really need to jump forward?

> And with an ADD or a SUB instruction also some delay can be built on top of
> these instructions.

The opcode SH_PM_OP_ADD_IMM_R0 isn't enough?

Which other opcodes do you need?

Cheers,

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI March 24, 2009, 1:41 p.m. UTC | #4
Hi Magnus
> Right, I understand. This becomes a bit more complicated but it's not
> so strange. As long as the two pass setup() is ok (first pass without
> buffer) then I'm ok.
>
> But do we (you!) really need to jump forward?
>   
Not really but I'd like to have no constraint if possible
>   
>> And with an ADD or a SUB instruction also some delay can be built on top of
>> these instructions.
>>     
>
> The opcode SH_PM_OP_ADD_IMM_R0 isn't enough?
>   
Yes I think so.

Have you time to extend your code or is it ok for you if I do the 
required update?

Regards
 Francesco
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Magnus Damm March 25, 2009, 10:10 a.m. UTC | #5
On 3/24/09, Francesco VIRLINZI <francesco.virlinzi@st.com> wrote:

> > But do we (you!) really need to jump forward?
> >
> >
>  Not really but I'd like to have no constraint if possible

Then I vote for adding it later when there is a direct need. You can
implement delay using backward jump only, right?

>  Have you time to extend your code or is it ok for you if I do the required
> update?

Please write a patch youself for now. And feel free to post it if
you'd like. Don't spend too much time at this point though. Other
people may come up with better code...

Yoshii-san, any comments?

Cheers!

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
takasi-y@ops.dti.ne.jp March 25, 2009, 2:46 p.m. UTC | #6
> Yoshii-san, any comments?
I still prefer to write them in _real_ assember (without having any good idea), though.

> > > But do we (you!) really need to jump forward?
> >  Not really but I'd like to have no constraint if possible
> Then I vote for adding it later when there is a direct need. You can
> implement delay using backward jump only, right?

Because this is a kind of assembler, we can use its technique, like
making pointer link of undefined labels on its reference,
 and resolve them following the link when the label is defined.
Then the code will be

 /* forward ref. This make link because label is not resolved */
 sh_pm_op(info, SH_PM_OP_BT, sh_pm_ref(info, &label));
 /* define label, and resolve above using linked list */
 sh_pm_label(info, &label); /* define label, and resolve above */
 /* backward ref. This simply use label value */
 sh_pm_op(info, SH_PM_OP_BT, sh_pm_ref(info, &label));

But, I don't think we need even backward jump.
What we want is conditional wait and delay, isn't it?

SH_PM_OP_WAIT_UNTIL_EQ(addr, value) while(read(addr)!=value)/*wait*/;
SH_PM_OP_WAIT_UNTIL_SET(addr, mask) while(!(read(addr)&mask))/*wait*/;
SH_PM_OP_WAIT_UNTIL_CLR(addr, mask) while(read(addr)&mask)/*wait*/;
SH_PM_OP_DELAY_LOOP(count) while(count--)/*wait*/;

/yoshii
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Magnus Damm March 30, 2009, 2:45 a.m. UTC | #7
On Wed, Mar 25, 2009 at 11:46 PM,  <takasi-y@ops.dti.ne.jp> wrote:
>> Yoshii-san, any comments?
> I still prefer to write them in _real_ assember (without having any good idea), though.

I think Francesco has more complex needs. Since his processor lacks
instruction cache prefetching opcodes, he is forced to populate the
instruction cache "by hand" with jump instructions. That will of
course be "_real_" assembly, but with magic jump instructions added in
the middle to support instruction cache preload. I prefer to build-in
the cache population into the interpreter/JIT code instead. That way
we can have the same interpreter regardless if we chose to preload in
cache or execute from onchip ram.

I think Yoshii-san is proposing breaking up code into board-specific
and cpu-specific assembly code, which gets copied and run.

Francesco, can you convince yoshii-san why we should add support for
an interpreter? =)

>> > > But do we (you!) really need to jump forward?
>> >  Not really but I'd like to have no constraint if possible
>> Then I vote for adding it later when there is a direct need. You can
>> implement delay using backward jump only, right?
>
> Because this is a kind of assembler, we can use its technique, like
> making pointer link of undefined labels on its reference,
>  and resolve them following the link when the label is defined.
> Then the code will be
>
>  /* forward ref. This make link because label is not resolved */
>  sh_pm_op(info, SH_PM_OP_BT, sh_pm_ref(info, &label));
>  /* define label, and resolve above using linked list */
>  sh_pm_label(info, &label); /* define label, and resolve above */
>  /* backward ref. This simply use label value */
>  sh_pm_op(info, SH_PM_OP_BT, sh_pm_ref(info, &label));

Sounds pretty clean. I guess it will become a bit more complex since
multiple opcomes may jump to the same label. So we may need to do a
linked list with per-opcode allocation. Unless we misuse the IMM field
in the opcode for a single linked list somehow. =)

> But, I don't think we need even backward jump.
> What we want is conditional wait and delay, isn't it?
>
> SH_PM_OP_WAIT_UNTIL_EQ(addr, value) while(read(addr)!=value)/*wait*/;
> SH_PM_OP_WAIT_UNTIL_SET(addr, mask) while(!(read(addr)&mask))/*wait*/;
> SH_PM_OP_WAIT_UNTIL_CLR(addr, mask) while(read(addr)&mask)/*wait*/;
> SH_PM_OP_DELAY_LOOP(count) while(count--)/*wait*/;

I wonder if we can make those opcodes fit with the current format?
Maybe no. They look fine with me though, but I'm not sure about
Francescos use case.

I'll try to find time to post V2 this or next week.

Cheers,

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI March 30, 2009, 7:02 a.m. UTC | #8
Hi Magnus, Yoshii-san
> Francesco, can you convince yoshii-san why we should add support for
> an interpreter? =)
>   
I can try ;-)
Than: I would push the interpreter solution because it will allow us to 
be free in the future.
If all the issue on 'cache preload' 'interpreter-instruction' are 
resolved in 'one-shot' right now
 in the future for each new SOC we will have only to resolve 'what it 
has to be done' and not 'how'....
This simplifies our development flow because we don't have to rediscover 
the wheel with always the same
 issue.
I know the interpreter will not allow 'optimized code' but I think the 
suspend assembly code doesn't have
 to be fast, it has to be right and for this reason I think it has to be 
written one time for ever...
Moreover an assembly code SOC oriented can not be seen as 'general 
purpose' solution while the interpreter
 can be 'theoretically' used by everybody.
>   
>> But, I don't think we need even backward jump.
>> What we want is conditional wait and delay, isn't it?
>>
>> SH_PM_OP_WAIT_UNTIL_EQ(addr, value) while(read(addr)!=value)/*wait*/;
>> SH_PM_OP_WAIT_UNTIL_SET(addr, mask) while(!(read(addr)&mask))/*wait*/;
>> SH_PM_OP_WAIT_UNTIL_CLR(addr, mask) while(read(addr)&mask)/*wait*/;
>> SH_PM_OP_DELAY_LOOP(count) while(count--)/*wait*/;
>>     
>
> I wonder if we can make those opcodes fit with the current format?
> Maybe no. They look fine with me though, but I'm not sure about
> Francescos use case.
>   
Enough good also for me but with a little change just one is enough:

SH_PM_OP_WAIT_UNTIL_EQ(addr, mask, value) while((read(addr) & mask) != value); /*wait*/;

In this manner it doesn't matter what each bit does (in the same word 
some bits could be set and some other could be reset).
Regards
 Francesco
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paul Mundt March 31, 2009, 8:42 a.m. UTC | #9
On Mon, Mar 30, 2009 at 09:02:54AM +0200, Francesco VIRLINZI wrote:
> Hi Magnus, Yoshii-san
> >Francesco, can you convince yoshii-san why we should add support for
> >an interpreter? =)
> >  
> I can try ;-)
> Than: I would push the interpreter solution because it will allow us to 
> be free in the future.
> If all the issue on 'cache preload' 'interpreter-instruction' are 
> resolved in 'one-shot' right now
> in the future for each new SOC we will have only to resolve 'what it 
> has to be done' and not 'how'....
> This simplifies our development flow because we don't have to rediscover 
> the wheel with always the same
> issue.
> I know the interpreter will not allow 'optimized code' but I think the 
> suspend assembly code doesn't have
> to be fast, it has to be right and for this reason I think it has to be 
> written one time for ever...
> Moreover an assembly code SOC oriented can not be seen as 'general 
> purpose' solution while the interpreter
> can be 'theoretically' used by everybody.

There are trade-offs either way. I tend to agree with Yoshii-san that
pushing the interpreter for everyone is a mistake, although I don't
disagree that it might be useful for some parts in the future. The real
question comes down to how different are the requirements for those
parts, and if there is not going to be any effort to push support
upstream for them, then there is hardly any reason to make the rest of
the in-tree parts suffer the pain of dealing with the interpreter.

We need to see hard requirements here, in technical detail, not
hand-waving about needing to be flexible for parts and requirements that
never materialize. Assembly stubs do work for the vast majority of cases
we have today, and the current model fits the CPU/board split pretty
well.

While I don't mind supporting multiple methods to support suspend (ie,
the interpreter for parts that want it, and common assembly stubs for
those that don't), we do not want to force all of the existing parts to
deal with it if they don't wish to.

The burden of proof is on you to point out why we need the interpreter,
rather than rationale for keeping it out-of-tree.

I am all for keeping the code as flexible and accomodating as possible,
but I draw the line at making upstream components suffer to accomodate
out-of-tree components that have no effort being put behind them to get
them merged.

Still, if the interpreter is clean enough, there is no harm in supporting
it as an optional component.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Magnus Damm April 15, 2009, 11:15 a.m. UTC | #10
On Tue, Mar 31, 2009 at 5:42 PM, Paul Mundt <lethal@linux-sh.org> wrote:
> We need to see hard requirements here, in technical detail, not
> hand-waving about needing to be flexible for parts and requirements that
> never materialize. Assembly stubs do work for the vast majority of cases
> we have today, and the current model fits the CPU/board split pretty
> well.

Yes, assembly stubs work fine for the SuperH Mobile sleep modes
implemented so far. I suspect that upcoming "R-standby mode" will be
easier to support with an interpreter though. Time will tell.

Francesco, if you feel like it and have time available, please
consider submitting support for some ST cpu/board combination
upstream. That may make it easier to motivate why an interpreter is
needed.

Cheers,

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paul Mundt April 15, 2009, 11:23 a.m. UTC | #11
On Wed, Apr 15, 2009 at 08:15:12PM +0900, Magnus Damm wrote:
> On Tue, Mar 31, 2009 at 5:42 PM, Paul Mundt <lethal@linux-sh.org> wrote:
> > We need to see hard requirements here, in technical detail, not
> > hand-waving about needing to be flexible for parts and requirements that
> > never materialize. Assembly stubs do work for the vast majority of cases
> > we have today, and the current model fits the CPU/board split pretty
> > well.
> 
> Yes, assembly stubs work fine for the SuperH Mobile sleep modes
> implemented so far. I suspect that upcoming "R-standby mode" will be
> easier to support with an interpreter though. Time will tell.
> 
As long as there are users for it, then we can look at supporting it. The
main thing is that it is supported as an optional method for platforms to
do finer grained support outside of the assembly stubs, and not making it
a requirement for every platform.

> Francesco, if you feel like it and have time available, please
> consider submitting support for some ST cpu/board combination
> upstream. That may make it easier to motivate why an interpreter is
> needed.
> 
If the ST CPUs and boards were upstream then making these sorts of
decisions is a lot easier. As it is now, while we certainly want to
accomodate these CPUs as much as possible, we are likewise not going to
introduce undue burden on in-tree platforms for out-of-tree code,
especially since it gets very difficult to make any changes in-tree
without having any idea what the implications are out-of-tree.

So, I'm willing to entertain an interpreter that satisfies the needs of
in-tree components. If this is to be extended for ST parts, those parts
need to be pushed upstream first. On the other hand, it should be easy to
build on top of whatever trivial interpreter gets integrated, and just
patch on top of that for out-of-tree use if an upstream merge is never
going to happen.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI April 16, 2009, 2:15 p.m. UTC | #12
Hi Paul
I understand your point of view.
And it's correct! It isn't possible to support something that doesn't exist.

Unfortunately I can not merge our tree with the original sh-tree at 
least now.

Therefore fell free to see my request as a "wish" not as a request...
The extra stuff our SOC requires will be done internally to ST.

In any case I will share all the stuff I can.

Regards
 Francesco
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI April 16, 2009, 2:22 p.m. UTC | #13
Hi Magnus
>
> Yes, assembly stubs work fine for the SuperH Mobile sleep modes
> implemented so far. I suspect that upcoming "R-standby mode" will be
> easier to support with an interpreter though. Time will tell.
>   
What do you mean with "R-standby mode"?
Regards
 Francesco
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Magnus Damm April 17, 2009, 2:07 a.m. UTC | #14
On Thu, Apr 16, 2009 at 11:22 PM, Francesco VIRLINZI
<francesco.virlinzi@st.com> wrote:
> Hi Magnus
>>
>> Yes, assembly stubs work fine for the SuperH Mobile sleep modes
>> implemented so far. I suspect that upcoming "R-standby mode" will be
>> easier to support with an interpreter though. Time will tell.
>>
>
> What do you mean with "R-standby mode"?

It's a SuperH Mobile specific standby mode where most hardware blocks
are powered off. So we need to restore many registers in the resume
path. I suspect some kind of interpeter will make saving and restoring
registers easier, especially the memory controller registers that need
to be re-initialized before the system memory can be taken out of
self-refresh.

Have a look at the following presentation for more information about
the standby modes on SuperH Mobile:

http://www.celinuxforum.org/CelfPubWiki/ELC2009Presentations?action=AttachFile&do=view&target=Runtime-Power-Management-on-SuperH-Mobile-20090407.pdf

Cheers,

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI April 17, 2009, 6:44 a.m. UTC | #15
Hi Magnus
> Have a look at the following presentation for more information about
> the standby modes on SuperH Mobile:
>
> http://www.celinuxforum.org/CelfPubWiki/ELC2009Presentations?action=AttachFile&do=view&target=Runtime-Power-Management-on-SuperH-Mobile-20090407.pdf
>
>   
I just completed something similar on our ST40 (with PMB enabled).
We put the DRAM in self refresh an after that we totally turn-off the 
SOC removing the power.
An external little micro has to detect the wakeup event and has to 
turn-on the SOC.
The bootloader "understands" linux is frozen in memory and jump directly 
on linux.

Internally we call that "hibernation on memory" and clearly it needs 
update in both linux/bootloader...
But from the device driver point of view this is a normal hibernation 
while for the main core this is a special 'boot'.

Currently as major change I did are in the TMU/PMB and some asm code to 
manage the "reboot".

Do you think there is something shareable?

Ciao
 Francesco
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Magnus Damm April 17, 2009, 10:39 a.m. UTC | #16
Hi Francesco,

On Fri, Apr 17, 2009 at 3:44 PM, Francesco VIRLINZI
<francesco.virlinzi@st.com> wrote:
> I just completed something similar on our ST40 (with PMB enabled).
> We put the DRAM in self refresh an after that we totally turn-off the SOC
> removing the power.
> An external little micro has to detect the wakeup event and has to turn-on
> the SOC.
> The bootloader "understands" linux is frozen in memory and jump directly on
> linux.
>
> Internally we call that "hibernation on memory" and clearly it needs update
> in both linux/bootloader...
> But from the device driver point of view this is a normal hibernation while
> for the main core this is a special 'boot'.

Sounds a bit similar to U-standby mode on SuperH Mobile.

> Currently as major change I did are in the TMU/PMB and some asm code to
> manage the "reboot".
>
> Do you think there is something shareable?

For boot loader, do you use upstream U-boot? That would be interesting to see.

Apart from that, this approach is low on my list. This because it
affects a lot of code and it may be difficult to maintain. I want to
prioritize R-standby where we can power off most of the CPU but still
resume from RAM without boot loader modifications... Do you have a
mode similar to R-standby?

Thanks for your offer!

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI April 17, 2009, noon UTC | #17
Hi Magnus
> For boot loader, do you use upstream U-boot? That would be interesting to see.
>   
We are moving on an internal light boot-loader.
> Apart from that, this approach is low on my list. This because it
> affects a lot of code and it may be difficult to maintain. I want to
> prioritize R-standby where we can power off most of the CPU but still
> resume from RAM without boot loader modifications...
This means the main CPU core is still powered. Is it?
While in the hibernation on memory the CPU runs from a standard power-on.
>  Do you have a mode similar to R-standby?
>   
No we haven't.
Regards
 Francesco
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jean-Christophe PLAGNIOL-VILLARD April 17, 2009, 9:38 p.m. UTC | #18
On 19:39 Fri 17 Apr     , Magnus Damm wrote:
> Hi Francesco,
> 
> On Fri, Apr 17, 2009 at 3:44 PM, Francesco VIRLINZI
> <francesco.virlinzi@st.com> wrote:
> > I just completed something similar on our ST40 (with PMB enabled).
> > We put the DRAM in self refresh an after that we totally turn-off the SOC
> > removing the power.
> > An external little micro has to detect the wakeup event and has to turn-on
> > the SOC.
> > The bootloader "understands" linux is frozen in memory and jump directly on
> > linux.
> >
> > Internally we call that "hibernation on memory" and clearly it needs update
> > in both linux/bootloader...
> > But from the device driver point of view this is a normal hibernation while
> > for the main core this is a special 'boot'.
> 
> Sounds a bit similar to U-standby mode on SuperH Mobile.
> 
> > Currently as major change I did are in the TMU/PMB and some asm code to
> > manage the "reboot".
> >
> > Do you think there is something shareable?
> 
> For boot loader, do you use upstream U-boot? That would be interesting to see.
no old u-boot version 1.3.1 with a diferrent implemntation as the actual SH4
Mainline support

Actually it will be nice to have it, I've this exact hardware design and wish
to do it we on a 7105.

Francesco do you have any patch or tree were we can take a look on it?

Best Regards,
J.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Magnus Damm April 20, 2009, 10:26 a.m. UTC | #19
Hi Francesco!

On Fri, Apr 17, 2009 at 9:00 PM, Francesco VIRLINZI
<francesco.virlinzi@st.com> wrote:
> Hi Magnus
>>
>> For boot loader, do you use upstream U-boot? That would be interesting to
>> see.
>>
>
> We are moving on an internal light boot-loader.

Sounds lightweight and nice. =)

>> Apart from that, this approach is low on my list. This because it
>> affects a lot of code and it may be difficult to maintain. I want to
>> prioritize R-standby where we can power off most of the CPU but still
>> resume from RAM without boot loader modifications...
>
> This means the main CPU core is still powered. Is it?

Some part of the CPU is still powered on. So it remembers a little
state and can resume from internal on-chip RAM.

> While in the hibernation on memory the CPU runs from a standard power-on.

I understand.

>>
>>  Do you have a mode similar to R-standby?
>>
>
> No we haven't.

Ok.
Can you disable power to certain parts of the SoC? Do you have
multiple power domains?

Do you need functions for saving and restoring hardware state in
device drivers? I've been talking a bit about run time device power
management. Maybe that would be useful for you guys?

Cheers,

/ magnus
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jean-Christophe PLAGNIOL-VILLARD April 20, 2009, 12:27 p.m. UTC | #20
On 14:33 Mon 20 Apr     , Francesco VIRLINZI wrote:
> Hi Jean
>>
>> Actually it will be nice to have it, I've this exact hardware design and wish
>> to do it we on a 7105.
>>
>> Francesco do you have any patch or tree were we can take a look on it?
>>   
> All the STLinux distribution (RPM and SRPM formats) is freely available @
more precisely please

Best Regards,
J.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI April 20, 2009, 12:33 p.m. UTC | #21
Hi Jean
>
> Actually it will be nice to have it, I've this exact hardware design and wish
> to do it we on a 7105.
>
> Francesco do you have any patch or tree were we can take a look on it?
>   
All the STLinux distribution (RPM and SRPM formats) is freely available @

www.stlinux.com

Regards
 Francesco

--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI April 20, 2009, 12:55 p.m. UTC | #22
Jean-Christophe PLAGNIOL-VILLARD ha scritto:
> On 14:33 Mon 20 Apr     , Francesco VIRLINZI wrote:
>   
>> Hi Jean
>>     
>>> Actually it will be nice to have it, I've this exact hardware design and wish
>>> to do it we on a 7105.
>>>
>>> Francesco do you have any patch or tree were we can take a look on it?
>>>   
>>>       
>> All the STLinux distribution (RPM and SRPM formats) is freely available @
>>     
> more precisely please
>   
@
ftp://ftp.stlinux.com/pub/stlinux/2.3/SRPMS/

Regards
 Francesco
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jean-Christophe PLAGNIOL-VILLARD April 20, 2009, 1:03 p.m. UTC | #23
On 14:55 Mon 20 Apr     , Francesco VIRLINZI wrote:
> Jean-Christophe PLAGNIOL-VILLARD ha scritto:
>> On 14:33 Mon 20 Apr     , Francesco VIRLINZI wrote:
>>   
>>> Hi Jean
>>>     
>>>> Actually it will be nice to have it, I've this exact hardware design and wish
>>>> to do it we on a 7105.
>>>>
>>>> Francesco do you have any patch or tree were we can take a look on it?
>>>>         
>>> All the STLinux distribution (RPM and SRPM formats) is freely available @
>>>     
>> more precisely please
>>   
> @
> ftp://ftp.stlinux.com/pub/stlinux/2.3/SRPMS/
I mean the patch, git tree commit

Best Regards,
J.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jean-Christophe PLAGNIOL-VILLARD April 20, 2009, 1:15 p.m. UTC | #24
On 15:30 Mon 20 Apr     , Michael Trimarchi wrote:
> Jean-Christophe PLAGNIOL-VILLARD wrote:
>> On 14:55 Mon 20 Apr     , Francesco VIRLINZI wrote:
>>   
>>> Jean-Christophe PLAGNIOL-VILLARD ha scritto:
>>>     
>>>> On 14:33 Mon 20 Apr     , Francesco VIRLINZI wrote:
>>>>         
>>>>> Hi Jean
>>>>>             
>>>>>> Actually it will be nice to have it, I've this exact hardware design and wish
>>>>>> to do it we on a 7105.
>>>>>>
>>>>>> Francesco do you have any patch or tree were we can take a look on it?
>>>>>>                   
>>>>> All the STLinux distribution (RPM and SRPM formats) is freely available @
>>>>>             
>>>> more precisely please
>>>>         
>>> @
>>> ftp://ftp.stlinux.com/pub/stlinux/2.3/SRPMS/
>>>     
>> I mean the patch, git tree commit
>>   
> maybe, they has an internal repository, so maybe the good question can  
> be, what are the
> affected files?
no there is a public git tree

Best Regards,
J.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michael Trimarchi April 20, 2009, 1:30 p.m. UTC | #25
Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 14:55 Mon 20 Apr     , Francesco VIRLINZI wrote:
>   
>> Jean-Christophe PLAGNIOL-VILLARD ha scritto:
>>     
>>> On 14:33 Mon 20 Apr     , Francesco VIRLINZI wrote:
>>>   
>>>       
>>>> Hi Jean
>>>>     
>>>>         
>>>>> Actually it will be nice to have it, I've this exact hardware design and wish
>>>>> to do it we on a 7105.
>>>>>
>>>>> Francesco do you have any patch or tree were we can take a look on it?
>>>>>         
>>>>>           
>>>> All the STLinux distribution (RPM and SRPM formats) is freely available @
>>>>     
>>>>         
>>> more precisely please
>>>   
>>>       
>> @
>> ftp://ftp.stlinux.com/pub/stlinux/2.3/SRPMS/
>>     
> I mean the patch, git tree commit
>   
maybe, they has an internal repository, so maybe the good question can 
be, what are the
affected files?
> Best Regards,
> J.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>   

--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francesco VIRLINZI April 21, 2009, 7:17 a.m. UTC | #26
Hi Magnus
> Can you disable power to certain parts of the SoC? Do you have
> multiple power domains?
>   
Not currently... It should be in the future.
But hibernation on memory works with a 'power domain' board based 
therefore it's easy to implement in the customer board.
> Do you need functions for saving and restoring hardware state in
> device drivers?
For some IP it's required.
>  I've been talking a bit about run time device power
> management. Maybe that would be useful for you guys?
>   
What do you have in mind?
Currently we release a kernel tool to leave the customer able to design 
their our power profile.
This means the system is moved from a profile to an other....

A real runtime power management requires a support linux currently 
doesn't have.

Regards
 Francesco
> Cheers,
>
> / magnus
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>   

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

Patch

--- 0001/arch/sh/kernel/cpu/shmobile/pm.c
+++ work/arch/sh/kernel/cpu/shmobile/pm.c	2009-03-23 18:00:51.000000000 +0900
@@ -16,6 +16,167 @@ 
 #include <asm/suspend.h>
 #include <asm/uaccess.h>
 
+#define SH_PM_OP_IMM_OFFS 8
+#define SH_PM_OP_JMP_OFFS 12
+#define SH_PM_OP_SIZE 16
+
+#define SH_PM_OP_MOV_IMM_R0	0
+#define SH_PM_OP_MOV_MEM8_R0	1
+#define SH_PM_OP_MOV_MEM16_R0	2
+#define SH_PM_OP_MOV_MEM32_R0	3
+#define SH_PM_OP_MOV_R0_MEM8	4
+#define SH_PM_OP_MOV_R0_MEM16	5
+#define SH_PM_OP_MOV_R0_MEM32	6
+#define SH_PM_OP_AND_IMM_R0	7
+#define SH_PM_OP_OR_IMM_R0	8
+#define SH_PM_OP_ADD_IMM_R0	9
+#define SH_PM_OP_SLEEP		10
+#define SH_PM_OP_RTS		11
+#define SH_PM_OP_NR		12
+
+extern unsigned char sh_pm_op_base[SH_PM_OP_SIZE * SH_PM_OP_NR];
+
+struct sh_pm_op_info {
+	unsigned char *buf;
+	unsigned int nr_ops;
+	void (*setup)(struct sh_pm_op_info *);
+	void (*run)(struct sh_pm_op_info *);
+};
+
+static void sh_pm_op(struct sh_pm_op_info *info, int op, unsigned int data)
+{
+	unsigned int size = SH_PM_OP_SIZE;
+	unsigned char *buf = info->buf;
+
+	if (buf) {
+		buf += info->nr_ops * size;
+		memcpy(buf, &sh_pm_op_base[op * size], size);
+		*(unsigned int *)(buf + SH_PM_OP_IMM_OFFS) = data;
+	}
+	info->nr_ops++;
+}
+
+static void sh_pm_run(struct sh_pm_op_info *info)
+{
+	void (*snippet)(void);
+
+	/* preload in cache */
+	snippet = (void *)(info->buf + SH_PM_OP_JMP_OFFS);
+	snippet();
+
+	/* execute in cache */
+	snippet = (void *)info->buf;
+	snippet();
+}
+
+int sh_pm_mode_init(struct sh_pm_op_info *info)
+{
+	/* run once without buffer to calculate amount of memory needed */
+	info->buf = NULL;
+	info->nr_ops = 0;
+	info->setup(info);
+
+	info->buf = kmalloc(info->nr_ops * SH_PM_OP_SIZE, GFP_KERNEL);
+	if (!info->buf)
+		return -ENOMEM;
+
+	/* run second time with buffer to generate actual code */
+	info->nr_ops = 0;
+	info->setup(info);
+	return 0;
+}
+
+void sh_pm_mode_cleanup(struct sh_pm_op_info *info)
+{
+	kfree(info->buf);
+}
+
+/* "sleep" mode */
+
+static void sh_mobile_pm_stbcr_setup(struct sh_pm_op_info *info,
+				     unsigned int mode)
+{
+	sh_pm_op(info, SH_PM_OP_MOV_IMM_R0, mode);
+	sh_pm_op(info, SH_PM_OP_MOV_R0_MEM32, 0xa4150020); /* STBCR */
+}
+
+static void sh_mobile_pm_sleep_setup(struct sh_pm_op_info *info)
+{
+	/* make sure STBCR is cleared, execute sleep, return */
+	sh_mobile_pm_stbcr_setup(info, 0);
+	sh_pm_op(info, SH_PM_OP_SLEEP, 0);
+	sh_pm_op(info, SH_PM_OP_RTS, 0);
+}
+
+static struct sh_pm_op_info sh_mobile_pm_sleep = {
+	.setup = sh_mobile_pm_sleep_setup,
+	.run = sh_pm_run,
+};
+
+/* "sleep" mode with system memory in self-refresh */
+
+static void sh_mobile_pm_sf_suspend(struct sh_pm_op_info *info)
+{
+	/* SDRAM: disable power down and put in self-refresh mode */
+	sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, 0xfe400008); /* SDCR0 */
+	sh_pm_op(info, SH_PM_OP_OR_IMM_R0, 0x00000400);
+	sh_pm_op(info, SH_PM_OP_AND_IMM_R0, 0xffff7fff);
+	sh_pm_op(info, SH_PM_OP_MOV_R0_MEM32, 0xfe400008); /* SDCR0 */
+}
+
+static void sh_mobile_pm_sf_restore(struct sh_pm_op_info *info)
+{
+	/* SDRAM: put back in auto-refresh mode */
+	sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, 0xfe400008); /* SDCR0 */
+	sh_pm_op(info, SH_PM_OP_AND_IMM_R0, 0xfffffbff);
+	sh_pm_op(info, SH_PM_OP_MOV_R0_MEM32, 0xfe400008); /* SDCR0 */
+	sh_pm_op(info, SH_PM_OP_MOV_MEM32_R0, 0xfe40001c); /* RTCOR */
+	sh_pm_op(info, SH_PM_OP_ADD_IMM_R0, (unsigned int)-1);
+	sh_pm_op(info, SH_PM_OP_OR_IMM_R0, 0xa55a0000);
+	sh_pm_op(info, SH_PM_OP_MOV_R0_MEM32, 0xfe400018); /* RTCNT */
+}
+
+static void sh_mobile_pm_sleep_sf_setup(struct sh_pm_op_info *info)
+{
+	/* setup self-refresh, clear STBCR, execute sleep, restore */
+	sh_mobile_pm_sf_suspend(info);
+	sh_mobile_pm_stbcr_setup(info, 0);
+	sh_pm_op(info, SH_PM_OP_SLEEP, 0);
+	sh_mobile_pm_sf_restore(info);
+	sh_pm_op(info, SH_PM_OP_RTS, 0);
+}
+
+static struct sh_pm_op_info sh_mobile_pm_sleep_sf = {
+	.setup = sh_mobile_pm_sleep_sf_setup,
+	.run = sh_pm_run,
+};
+
+/* "standby" mode with system memory in self-refresh */
+
+static void sh_mobile_pm_standby_sf_setup(struct sh_pm_op_info *info)
+{
+	/* setup self-refresh, set STBCR, execute sleep, restore */
+	sh_mobile_pm_sf_suspend(info);
+	sh_mobile_pm_stbcr_setup(info, 0x80);
+	sh_pm_op(info, SH_PM_OP_SLEEP, 0);
+	sh_mobile_pm_stbcr_setup(info, 0);
+	sh_mobile_pm_sf_restore(info);
+	sh_pm_op(info, SH_PM_OP_RTS, 0);
+}
+
+static struct sh_pm_op_info sh_mobile_pm_standby_sf = {
+	.setup = sh_mobile_pm_standby_sf_setup,
+	.run = sh_pm_run,
+};
+
+
+static void sh_mobile_pm_setup(void)
+{
+	sh_pm_mode_init(&sh_mobile_pm_sleep);
+	sh_pm_mode_init(&sh_mobile_pm_sleep_sf);
+	sh_pm_mode_init(&sh_mobile_pm_standby_sf);
+}
+
 /*
  * Sleep modes available on SuperH Mobile:
  *
@@ -85,6 +246,7 @@  static struct platform_suspend_ops sh_pm
 
 static int __init sh_pm_init(void)
 {
+	sh_mobile_pm_setup();
 	suspend_set_ops(&sh_pm_ops);
 	return 0;
 }
--- 0001/arch/sh/kernel/cpu/shmobile/sleep.S
+++ work/arch/sh/kernel/cpu/shmobile/sleep.S	2009-03-23 17:24:34.000000000 +0900
@@ -123,3 +123,112 @@  sh_mobile_standby_end:
 
 ENTRY(sh_mobile_standby_size)
 	.long sh_mobile_standby_end - sh_mobile_standby
+
+ENTRY(sh_pm_op_base)
+sh_pm_op_mov_imm_r0:		/* @ SH_PM_OP_MOV_IMM_R0 * SH_PM_OP_SIZE */
+	mov.l	0f, r0
+	bra	2f
+	 nop
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_mov_mem8_r0:		/* @ SH_PM_OP_MOV_MEM8_R0 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 mov.b	@r1, r0
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_mov_mem16_r0:		/* @ SH_PM_OP_MOV_MEM16_R0 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 mov.w	@r1, r0
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_mov_mem32_r0:		/* @ SH_PM_OP_MOV_MEM32_R0 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 mov.l	@r1, r0
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_mov_r0_mem8:		/* @ SH_PM_OP_MOV_R0_MEM8 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 mov.b	r0, @r1
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_mov_r0_mem16:		/* @ SH_PM_OP_MOV_R0_MEM16 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 mov.w	r0, @r1
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_mov_r0_mem32:		/* @ SH_PM_OP_MOV_R0_MEM32 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 mov.l	r0, @r1
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_and_imm_r0:		/* @ SH_PM_OP_AND_IMM_R0 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 and	r1, r0
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_or_imm_r0:		/* @ SH_PM_OP_OR_IMM_R0 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 or	r1, r0
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_add_imm_r0:		/* @ SH_PM_OP_ADD_IMM_R0 * SH_PM_OP_SIZE */
+2:	mov.l	0f, r1
+	bra	2f
+	 add	r1, r0
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_sleep:			/* @ SH_PM_OP_SLEEP * SH_PM_OP_SIZE */
+2:	sleep
+	bra	2f
+	 nop
+	nop
+0:	.long	0
+1:	bra	1f
+	 nop
+
+sh_pm_op_rts:			/* @ SH_PM_OP_RTS * SH_PM_OP_SIZE */
+2:	rts
+	 nop
+	nop
+	nop
+0:	.long	0
+1:	rts
+	 nop