From: Dmitry Osipenko <digetx@gmail.com>
To: Sowjanya Komatineni <skomatineni@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>,
Jonathan Hunter <jonathanh@nvidia.com>,
Mantravadi Karthik <mkarthik@nvidia.com>,
Shardar Mohammed <smohammed@nvidia.com>,
Timo Alho <talho@nvidia.com>,
"linux-tegra@vger.kernel.org" <linux-tegra@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-i2c@vger.kernel.org" <linux-i2c@vger.kernel.org>
Subject: Re: [PATCH V8 3/5] i2c: tegra: Add DMA Support
Date: Fri, 1 Feb 2019 06:14:14 +0300 [thread overview]
Message-ID: <20190201061414.05443ea1@dimatab> (raw)
In-Reply-To: <BYAPR12MB33986DDF4267ED1F499317B0C2920@BYAPR12MB3398.namprd12.prod.outlook.com>
В Fri, 1 Feb 2019 01:11:06 +0000
Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
> > > > + if (dma) {
> > > > + if (i2c_dev->msg_read) {
> > > > + chan = i2c_dev->rx_dma_chan;
> > > > + tegra_i2c_config_fifo_trig(i2c_dev,
> > > > xfer_size,
> > > > +
> > > > DATA_DMA_DIR_RX);
> > > > +
> > > > dma_sync_single_for_device(i2c_dev->dev, +
> > > > i2c_dev->dma_phys,
> > > > + xfer_size,
> > > > +
> > > > DMA_FROM_DEVICE);
> > >
> > > Do we really need this? We're not actually passing the device any
> > > data, so no caches to flush here. I we're cautious about flushing
> > > caches when we do write to the buffer (and I think we do that
> > > properly already), then there should be no need to do it here
> > > again.
> >
> > IIUC, DMA API has a concept of buffer handing which tells to use
> dma_sync_single_for_device() before issuing hardware job that touches
> the buffer and to use dma_sync_single_for_cpu() after hardware done
> the execution. In fact the CPU caches are getting flushed or
> invalidated as appropriate in a result.
> >
> > dma_sync_single_for_device(DMA_FROM_DEVICE) invalidates buffer in
> > the CPU cache, probably to avoid CPU evicting data from cache to
> > DRAM while hardware writes to the buffer. Hence this hunk is
> > correct.
> > > > + err = tegra_i2c_dma_submit(i2c_dev,
> > > > xfer_size);
> > > > + if (err < 0) {
> > > > + dev_err(i2c_dev->dev,
> > > > + "starting RX DMA
> > > > failed, err %d\n",
> > > > + err);
> > > > + goto unlock;
> > > > + }
> > > > + } else {
> > > > + chan = i2c_dev->tx_dma_chan;
> > > > + tegra_i2c_config_fifo_trig(i2c_dev,
> > > > xfer_size,
> > > > +
> > > > DATA_DMA_DIR_TX);
> > > > + dma_sync_single_for_cpu(i2c_dev->dev,
> > > > +
> > > > i2c_dev->dma_phys,
> > > > + xfer_size,
> > > > +
> > > > DMA_TO_DEVICE);
> > >
> > > This, on the other hand seems correct because we need to
> > > invalidate the caches for this buffer to make sure the data that
> > > we put there doesn't get overwritten.
> >
> > As I stated before in a comment to v6, this particular case of
> > dma_sync_single_for_cpu() usage is incorrect because CPU should
> > take ownership of the buffer after completion of hardwate job. But
> > in fact dma_sync_single_for_cpu(DMA_TO_DEVICE) is a NO-OP because
> > CPU doesn't need to flush or invalidate anything to take ownership
> > of the buffer if hardware did a read-only access.
> > >
> > > > + if (!i2c_dev->msg_read) {
> > > > + if (dma) {
> > > > + memcpy(buffer, msg->buf, msg->len);
> > > > +
> > > > dma_sync_single_for_device(i2c_dev->dev, +
> > > > i2c_dev->dma_phys,
> > > > + xfer_size,
> > > > +
> > > > DMA_TO_DEVICE);
> > >
> > > Again, here we properly flush the caches to make sure the data
> > > that we've written to the DMA buffer is visible to the DMA engine.
> > >
> >
> > +1 this is correct
> >
> >
> >
> > > > +
> > > > + if (i2c_dev->msg_read) {
> > > > + if (likely(i2c_dev->msg_err ==
> > > > I2C_ERR_NONE)) {
> > > > +
> > > > dma_sync_single_for_cpu(i2c_dev->dev,
> > > > +
> > > > i2c_dev->dma_phys,
> > > > +
> > > > xfer_size, +
> > > > DMA_FROM_DEVICE);
> > >
> > > Here we invalidate the caches to make sure we don't get stale
> > > data that may be in the caches for data that we're copying out of
> > > the DMA buffer. I think that's about all the cache maintenance
> > > that we real need.
> >
> > Correct.
> >
> > And technically here should be
> > dma_sync_single_for_cpu(DMA_TO_DEVICE) for the TX. But again, it's
> > a NO-OP.
>
> Is my below understanding correct? Can you please confirm?
>
> During Transmit to device:
> - Before writing msg data into dma buf by CPU, giving DMA ownership
> to CPU dma_sync_single_for_cpu with dir DMA_TO_DEVICE
>
I tried to take a look at it again and now thinking that your variant
is more correct. Still it's a bit difficult to judge because this case
is no-op.
> - After writing to dma buf by CPU, giving back the ownership to
> device to access buffer to send during DMA transmit
> dma_sync_single_for_device with dir DMA_TO_DEVICE
Correct.
> During Receiving from Device:
> - before submitting RX DMA to give buffer access to DMAengine
> dma_sync_single_for_Device(DMA_FROM_DEVICE)
Correct.
> - after DMA RX completion, giving dma ownership to CPU for reading
> dmabuf data written by DMA from device dma_sync_single_for_cpu with
> dir DMA_FROM_DEVICE
>
Correct.
next prev parent reply other threads:[~2019-02-01 3:14 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-31 6:16 [PATCH V8 1/5] i2c: tegra: Sort all the include headers alphabetically Sowjanya Komatineni
2019-01-31 6:16 ` Sowjanya Komatineni
2019-01-31 6:16 ` [PATCH V8 2/5] i2c: tegra: Add Bus Clear Master Support Sowjanya Komatineni
2019-01-31 6:16 ` Sowjanya Komatineni
2019-01-31 12:44 ` Thierry Reding
2019-01-31 15:16 ` Dmitry Osipenko
2019-01-31 6:16 ` [PATCH V8 3/5] i2c: tegra: Add DMA Support Sowjanya Komatineni
2019-01-31 6:16 ` Sowjanya Komatineni
2019-01-31 12:44 ` Thierry Reding
2019-01-31 16:41 ` Sowjanya Komatineni
2019-02-01 0:52 ` Dmitry Osipenko
2019-02-01 1:11 ` Sowjanya Komatineni
2019-02-01 3:14 ` Dmitry Osipenko [this message]
2019-02-01 4:19 ` Sowjanya Komatineni
2019-02-01 15:02 ` Dmitry Osipenko
2019-01-31 15:12 ` Dmitry Osipenko
2019-01-31 15:24 ` Dmitry Osipenko
2019-01-31 16:56 ` Sowjanya Komatineni
2019-01-31 17:11 ` Dmitry Osipenko
2019-01-31 17:25 ` Dmitry Osipenko
2019-01-31 17:38 ` Dmitry Osipenko
2019-01-31 17:38 ` Sowjanya Komatineni
2019-01-31 21:46 ` Sowjanya Komatineni
2019-02-01 0:54 ` Dmitry Osipenko
2019-01-31 6:16 ` [PATCH V8 4/5] i2c: tegra: Update transfer timeout Sowjanya Komatineni
2019-01-31 6:16 ` Sowjanya Komatineni
2019-01-31 12:48 ` Thierry Reding
2019-01-31 6:16 ` [PATCH V8 5/5] i2c: tegra: Add I2C interface timing support Sowjanya Komatineni
2019-01-31 6:16 ` Sowjanya Komatineni
2019-01-31 12:50 ` Thierry Reding
2019-01-31 12:45 ` [PATCH V8 1/5] i2c: tegra: Sort all the include headers alphabetically Thierry Reding
2019-01-31 15:14 ` Dmitry Osipenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190201061414.05443ea1@dimatab \
--to=digetx@gmail.com \
--cc=jonathanh@nvidia.com \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=mkarthik@nvidia.com \
--cc=skomatineni@nvidia.com \
--cc=smohammed@nvidia.com \
--cc=talho@nvidia.com \
--cc=thierry.reding@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.