All of lore.kernel.org
 help / color / mirror / Atom feed
* why iowrite32_rep() doesn't work, I have to use the iowrite32() with a loop
@ 2017-11-16 20:12 ayaka
  2017-11-18 15:50 ` Max Filippov
  0 siblings, 1 reply; 5+ messages in thread
From: ayaka @ 2017-11-16 20:12 UTC (permalink / raw)
  To: kernelnewbies

Hello All:

 ? I am writing a driver, I need to write a series of values into the 
registers. The old code use the writel_relaxed() to avoid flushing cache 
between echo of register. I want to use the recommended way of the io 
operations, so I choose the iowrite32()_req(), but I found what it wrote 
nothing, I read it at once after a memory barrier, there is no contents 
there. But it I use the iowrite32() with a loop, it works well and the 
registers of the device is configured.? What make this problem?

The io memory is assigned with devm_ioremap_resource().

void mpp_dev_write_seq(struct rockchip_mpp_dev *mpp_dev, unsigned long 
offset,
 ?????????????????????? void *buffer, unsigned long count)
{
 ??????? int i;
#if 1
 ??????? for (i = 0; i < count; i++) {
 ??????????????? u32 *cur = (u32 *)buffer;
 ??????????????? u32 pos = offset + i * 4;

 ??????????????? cur += i;
 ??????????????? mpp_debug(DEBUG_SET_REG, "write reg[%03d]: %08x\n", 
pos, *cur);
 ??????????????? iowrite32(*cur, mpp_dev->reg_base + pos);
}
#else
 ??????? iowrite32_rep(mpp_dev->reg_base + offset, buffer, count);
mb();
 ??????? for (i = 0; i < count; i++) {
 ??????????????? u32 cur = 0;
 ??????????????? u32 pos = offset / 4 + i;

 ??????????????? cur = ioread32(mpp_dev->reg_base + pos * 4);
 ??????????????? pr_info("get reg[%03d]: %08x\n", pos, cur);
}
#endif

}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* why iowrite32_rep() doesn't work, I have to use the iowrite32() with a loop
  2017-11-16 20:12 why iowrite32_rep() doesn't work, I have to use the iowrite32() with a loop ayaka
@ 2017-11-18 15:50 ` Max Filippov
  2017-11-19  3:36   ` ayaka
  0 siblings, 1 reply; 5+ messages in thread
From: Max Filippov @ 2017-11-18 15:50 UTC (permalink / raw)
  To: kernelnewbies

On Thu, Nov 16, 2017 at 12:12 PM, ayaka <ayaka@soulik.info> wrote:
> #if 1
>          for (i = 0; i < count; i++) {
>                  u32 *cur = (u32 *)buffer;
>                  u32 pos = offset + i * 4;
>
>                  cur += i;
>                  mpp_debug(DEBUG_SET_REG, "write reg[%03d]: %08x\n",
> pos, *cur);
>                  iowrite32(*cur, mpp_dev->reg_base + pos);
> }
> #else
>          iowrite32_rep(mpp_dev->reg_base + offset, buffer, count);
> mb();
>          for (i = 0; i < count; i++) {
>                  u32 cur = 0;
>                  u32 pos = offset / 4 + i;
>
>                  cur = ioread32(mpp_dev->reg_base + pos * 4);
>                  pr_info("get reg[%03d]: %08x\n", pos, cur);
> }
> #endif

The loop with iowrite32 writes consecutive u32 words from buffer
to consecutive IO memory locations. But iowrite32_rep writes
consecutive u32 words from buffer to the same IO memory location.
So they do different things when count > 1.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 5+ messages in thread

* why iowrite32_rep() doesn't work, I have to use the iowrite32() with a loop
  2017-11-18 15:50 ` Max Filippov
@ 2017-11-19  3:36   ` ayaka
  2017-11-19 13:56     ` Max Filippov
  0 siblings, 1 reply; 5+ messages in thread
From: ayaka @ 2017-11-19  3:36 UTC (permalink / raw)
  To: kernelnewbies



On 11/18/2017 11:50 PM, Max Filippov wrote:
> On Thu, Nov 16, 2017 at 12:12 PM, ayaka <ayaka@soulik.info> wrote:
>> #if 1
>>           for (i = 0; i < count; i++) {
>>                   u32 *cur = (u32 *)buffer;
>>                   u32 pos = offset + i * 4;
>>
>>                   cur += i;
>>                   mpp_debug(DEBUG_SET_REG, "write reg[%03d]: %08x\n",
>> pos / 4, *cur);
>>                   iowrite32(*cur, mpp_dev->reg_base + pos);
>> }
>> #else
>>           iowrite32_rep(mpp_dev->reg_base + offset, buffer, count);
>> mb();
>>           for (i = 0; i < count; i++) {
>>                   u32 cur = 0;
>>                   u32 pos = offset / 4 + i;
>>
>>                   cur = ioread32(mpp_dev->reg_base + pos * 4);
>>                   pr_info("get reg[%03d]: %08x\n", pos, cur);
>> }
>> #endif
> The loop with iowrite32 writes consecutive u32 words from buffer
> to consecutive IO memory locations. But iowrite32_rep writes
> consecutive u32 words from buffer to the same IO memory location.
> So they do different things when count > 1.
>
Thank you I think that explain why it doesn't work.

What I want is a relaxed version of the io{read,write}32, as I don't 
need to flush between I am writing the registers table into the 
registers. I only want to flush the cache at the last and isolated 
register which I will set later.

Is there any suggest about that?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* why iowrite32_rep() doesn't work, I have to use the iowrite32() with a loop
  2017-11-19  3:36   ` ayaka
@ 2017-11-19 13:56     ` Max Filippov
  2017-11-21 15:42       ` ayaka
  0 siblings, 1 reply; 5+ messages in thread
From: Max Filippov @ 2017-11-19 13:56 UTC (permalink / raw)
  To: kernelnewbies

On Sat, Nov 18, 2017 at 7:36 PM, ayaka <ayaka@soulik.info> wrote:
> What I want is a relaxed version of the io{read,write}32, as I don't need to
> flush between I am writing the registers table into the registers. I only
> want to flush the cache at the last and isolated register which I will set
> later.

None of these functions do anything with cache. And with
devm_ioremap_resource you will likely get an uncached mapping of your
IO memory, so you don't even need to manage cache.

What you still need to preserve the order of writes is a memory barrier,
and none of io{read,write}32 do it either. You can insert proper barrier
before the write to that last isolated register.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 5+ messages in thread

* why iowrite32_rep() doesn't work, I have to use the iowrite32() with a loop
  2017-11-19 13:56     ` Max Filippov
@ 2017-11-21 15:42       ` ayaka
  0 siblings, 0 replies; 5+ messages in thread
From: ayaka @ 2017-11-21 15:42 UTC (permalink / raw)
  To: kernelnewbies



On 11/19/2017 09:56 PM, Max Filippov wrote:
> On Sat, Nov 18, 2017 at 7:36 PM, ayaka <ayaka@soulik.info> wrote:
>> What I want is a relaxed version of the io{read,write}32, as I don't need to
>> flush between I am writing the registers table into the registers. I only
>> want to flush the cache at the last and isolated register which I will set
>> later.
> None of these functions do anything with cache. And with
> devm_ioremap_resource you will likely get an uncached mapping of your
> IO memory, so you don't even need to manage cache.
I didn't notice that the IO memory is not cached at the most platform, 
even the ldd3 have said that.
> What you still need to preserve the order of writes is a memory barrier,
> and none of io{read,write}32 do it either. You can insert proper barrier
> before the write to that last isolated register.
I see, thank you.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-11-21 15:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-16 20:12 why iowrite32_rep() doesn't work, I have to use the iowrite32() with a loop ayaka
2017-11-18 15:50 ` Max Filippov
2017-11-19  3:36   ` ayaka
2017-11-19 13:56     ` Max Filippov
2017-11-21 15:42       ` ayaka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.