[U-Boot] [PATCH] nvme: add more cache flushes

Bin Meng bmeng.cn at gmail.com
Wed Oct 16 10:11:23 UTC 2019


On Mon, Oct 14, 2019 at 7:11 PM Patrick Wildt <patrick at blueri.se> wrote:
>
> On an i.MX8MQ our nvme driver doesn't completely work since we are
> missing a few cache flushes.  One is the prp list, which is an extra
> buffer that we need to flush before handing it to the hardware.  Also
> the block read/write operations needs more cache flushes on this SoC.
>
> Signed-off-by: Patrick Wildt <patrick at blueri.se>
> ---
>  drivers/nvme/nvme.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
> index 2444e0270f..69d5e3eedc 100644
> --- a/drivers/nvme/nvme.c
> +++ b/drivers/nvme/nvme.c
> @@ -123,6 +123,9 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
>         }
>         *prp2 = (ulong)dev->prp_pool;
>
> +       flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
> +                          dev->prp_entry_num * sizeof(u64));
> +
>         return 0;
>  }
>
> @@ -717,9 +720,10 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr,
>         u16 lbas = 1 << (dev->max_transfer_shift - ns->lba_shift);
>         u64 total_lbas = blkcnt;
>
> -       if (!read)
> -               flush_dcache_range((unsigned long)buffer,
> -                                  (unsigned long)buffer + total_len);
> +       flush_dcache_range((unsigned long)buffer,
> +                          (unsigned long)buffer + total_len);

Why we need this for read?

> +       invalidate_dcache_range((unsigned long)buffer,
> +                               (unsigned long)buffer + total_len);
>
>         c.rw.opcode = read ? nvme_cmd_read : nvme_cmd_write;
>         c.rw.flags = 0;
> @@ -755,9 +759,8 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr,
>                 buffer += lbas << ns->lba_shift;
>         }
>
> -       if (read)
> -               invalidate_dcache_range((unsigned long)buffer,
> -                                       (unsigned long)buffer + total_len);
> +       invalidate_dcache_range((unsigned long)buffer,
> +                               (unsigned long)buffer + total_len);

Why we need this for write?

>
>         return (total_len - temp_len) >> desc->log2blksz;
>  }
> --

Regards,
Bin


More information about the U-Boot mailing list