why iowrite32_rep() doesn't work, I have to use the iowrite32() with a loop
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 }
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
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?
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
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.
participants (2)
-
ayaka -
Max Filippov