[U-Boot] [PATCH 2/3] common: rework bouncebuf implementation
Stephen Warren
swarren at wwwdotorg.org
Tue Nov 6 19:44:28 CET 2012
On 11/05/2012 04:54 PM, Simon Glass wrote:
> Hi Stephen,
>
> On Mon, Nov 5, 2012 at 3:04 PM, Stephen Warren <swarren at wwwdotorg.org> wrote:
>> The current bouncebuf API requires all parameters to be passed to both
>> bounce_buffer_start() and bounce_buffer_stop(). This works fine when
>> both functions are called from the same place. However, Tegra's MMC
>> driver splits the data setup and post-processing steps between two
>> functions, and passing all that state around separately would be painful.
>> Modify the bouncebuf API to accept a state structure as a parameter, so
>> that only a single struct needs to be passed to both APIs.
...
> I wonder if the dcache handling could be done here (and in the
> memcpy() below), perhaps under the control of a new flag. After the
> cache code in both drivers seems very similar.
Yes, that's a good idea. It cross my mind before, but I forgot to follow
up on it and realize that the cache management APIs are actually common,
not CPU-specific.
One question here. The MXS MMC driver contains:
> if (data->flags & MMC_DATA_WRITE) {
> /* Flush data to DRAM so DMA can pick them up */
> flush_dcache_range((uint32_t)bbstate.bounce_buffer,
> (uint32_t)(bbstate.bounce_buffer) +
> bbstate.len_aligned);
> }
>
> /* Invalidate the area, so no writeback into the RAM races with DMA */
> invalidate_dcache_range((uint32_t)priv->desc->cmd.address,
> (uint32_t)(priv->desc->cmd.address +
> bbstate.len_aligned));
It the invalidate_dcache_range() really necessary here? I would assume
that the flush_dcache_range() call marks the cache non-dirty, so there
can no longer be any write-backs to race with the DMA. Certainly, the
Tegra MMC driver doesn't include that invalidate call and appears to
work fine.
I agree with all your comments that I haven't quoted here, and will go
implement them.
>> -static inline int bounce_buffer_start(void **data, size_t len, void **backup,
>> - uint8_t flags)
>> +struct bounce_buffer_state {
>> + void *bounce_buffer;
>> + size_t len_aligned;
>> +};
>> +
>> +static inline int bounce_buffer_start(struct bounce_buffer_state *state,
>> + void *data, size_t len, uint8_t flags)
>> {
>> + state->bounce_buffer = data;
>> + state->len_aligned = len;
>
> Why do you need to do this if it is just a null implementation?
> Perhaps add a comment.
I wondered whether we should simply remove the dummy implementations
completely; it seems that if any MMC driver needs bouncebuf ever, it
always needs it. Hence, there should never be a case where these APIs
are called/referenced, yet CONFIG_BOUNCE_BUFFER is not set. However,
there is such a case right now; sc_sps_1.h enables the MXS MMC driver
but not the bounce buffer. Perhaps I should just send a patch to fix
that, and remove these dummy functions.
Aside from that, the reason these dummy functions need to set fields in
*state right now is that the MXS MMC driver unconditionally accesses
those fields, so they need to exist and contain valid data.
More information about the U-Boot
mailing list