diff mbox

[PATCHv3] dmaengine: fsl-edma: fixup reg offset and hw S/G support in big-endian model

Message ID 1411550642-12577-1-git-send-email-jingchang.lu@freescale.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Jingchang Lu Sept. 24, 2014, 9:24 a.m. UTC
The offset of all 8-/16-bit register in big-endian eDMA model are
swapped in a 32-bit size opposite those in the little-endian model.

The hardware Scatter/Gather requires the subsequent TCDs in memory
to be auto loaded should retain little endian independent of the
register endian model, the dma engine will do the swap if need.

This patch also use regular assignment for tcd variables r/w
instead of with io function previously that may not always be true.

Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
---
changes in v3:
 use unsigned long instead of u32 in reg offset swap cast to avoid warning.

changes in v2:
 simplify register offset swap calculation.
 use regular assignment for tcd variables r/w instead of io function.

 drivers/dma/fsl-edma.c | 106 ++++++++++++++++++++++++++-----------------------
 1 file changed, 57 insertions(+), 49 deletions(-)

Comments

Lothar Waßmann Sept. 24, 2014, 11:05 a.m. UTC | #1
Hi,

Jingchang Lu wrote:
> The offset of all 8-/16-bit register in big-endian eDMA model are
s/register/registers/

> swapped in a 32-bit size opposite those in the little-endian model.
> 
> The hardware Scatter/Gather requires the subsequent TCDs in memory
> to be auto loaded should retain little endian independent of the
> register endian model, the dma engine will do the swap if need.
> 
> This patch also use regular assignment for tcd variables r/w
> instead of with io function previously that may not always be true.
> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
> changes in v3:
>  use unsigned long instead of u32 in reg offset swap cast to avoid warning.
> 
> changes in v2:
>  simplify register offset swap calculation.
>  use regular assignment for tcd variables r/w instead of io function.
> 
>  drivers/dma/fsl-edma.c | 106 ++++++++++++++++++++++++++-----------------------
>  1 file changed, 57 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index 3c5711d..9ca55ee 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -177,16 +177,10 @@ struct fsl_edma_engine {
>  /*
>   * R/W functions for big- or little-endian registers
>   * the eDMA controller's endian is independent of the CPU core's endian.
> + * for the big-endian IP module, the offset for 8-bit or 16-bit register
s/for/For/

> + * should also be swapped oposite to that in little-endian IP.
s/oposite/opposite/

[...]
> @@ -459,20 +460,27 @@ static void fill_tcd_params(struct fsl_edma_engine *edma,
>  	u16 csr = 0;
>  
>  	/*
> -	 * eDMA hardware SGs require the TCD parameters stored in memory
> -	 * the same endian as the eDMA module so that they can be loaded
> -	 * automatically by the engine
> +	 * eDMA hardware SGs requires the TCDs to be auto loaded
> +	 * in the little endian whenver the register endian model,
"in little endian whatever the register endian model"

> +	 * So we put the value in little endian in memory, waitting
s/waitting/waiting/

> +	 * for fsl_set_tcd_params doing the swap.
fsl_set_tcd_params()



Lothar Waßmann
Russell King - ARM Linux Sept. 24, 2014, 12:03 p.m. UTC | #2
On Wed, Sep 24, 2014 at 01:05:10PM +0200, Lothar Waßmann wrote:
> Hi,
> 
> Jingchang Lu wrote:
> > +	 * eDMA hardware SGs requires the TCDs to be auto loaded
> > +	 * in the little endian whenver the register endian model,
> "in little endian whatever the register endian model"

Even that took several reads to work it out.

	eDMA hardware SGs require the TCDs to be stored in little endian
	format irrespective of the register endian model.

and I think that's all that needs to be said here.

However, as I realdy suggested, running this ruddy thing through sparse
would be a /very/ good idea, because it'll warn with:

+       tcd->daddr = cpu_to_le32(dst);

The reason it'll warn on that is because daddr is not declared with
__le32, etc - the types used in struct fsl_edma_hw_tcd tell sparse that
the values to be stored there are in _host_ endian format, but they're
being assigned little endian formatted data.

> > +	 * for fsl_set_tcd_params doing the swap.
> fsl_set_tcd_params()

That's the wrong function name anyway.  It's fsl_edma_set_tcd_params().

However, let's look at this a little more:

        fsl_edma_set_tcd_params(fsl_chan, tcd->saddr, tcd->daddr, tcd->attr,
                        tcd->soff, tcd->nbytes, tcd->slast, tcd->citer,
                        tcd->biter, tcd->doff, tcd->dlast_sga, tcd->csr);

Is it /really/ a good idea to read all that data out of the structure,
only to then have most of it saved into the stack, which
fsl_edma_set_tcd_params() then has to read back off the stack again?
With stuff like this, one has to wonder if there is much clue how to
write optimal C code in this driver.

This should be passing the tcd structure into fsl_edma_set_tcd_params().

Now, this function contains this comment:

        /*
         * TCD parameters have been swapped in fill_tcd_params(),
         * so just write them to registers in the cpu endian here
         */

Which is almost reasonable, but let's update it:

	TCD parameters are stored in struct fsl_edma_hw_tcd in little
	endian format.  However, we need to load the registers in
	<insert appropriate endianness - big|little|cpu> endian.

Now, remember that writel() and friends expect native CPU endian formatted
data (and yes, sparse checks this too) so that needs to be considered more.

Lastly, the driver seems to be a total mess of accessors.  In some places
it uses io{read,write}*, in other places, it uses plain {read,write}*.  It
should use either one set or the other set, and not mix these two.

I just spotted this badly formatted code too:

        for (i = 0; i < fsl_desc->n_tcds; i++)
                        dma_pool_free(fsl_desc->echan->tcd_pool,
                                        fsl_desc->tcd[i].vtcd,
                                        fsl_desc->tcd[i].ptcd);
...
                edma_writeb(fsl_chan->edma,
                                EDMAMUX_CHCFG_ENBL | EDMAMUX_CHCFG_SOURCE(slot),
                                muxaddr + ch_off);
Jingchang Lu Sept. 25, 2014, 6:42 a.m. UTC | #3
Pi0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+RnJvbTogTG90aGFyIFdhw59tYW5uIFttYWls
dG86TFdAS0FSTy1lbGVjdHJvbmljcy5kZV0NCj5TZW50OiBXZWRuZXNkYXksIFNlcHRlbWJlciAy
NCwgMjAxNCA3OjA1IFBNDQo+VG86IEx1IEppbmdjaGFuZy1CMzUwODMNCj5DYzogdmlub2Qua291
bEBpbnRlbC5jb207IGxpbnV4QGFybS5saW51eC5vcmcudWs7IGFybmRAYXJuZGIuZGU7IGxpbnV4
LQ0KPmtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7IGRtYWVuZ2luZUB2Z2VyLmtlcm5lbC5vcmc7IGxp
bnV4LWFybS0NCj5rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZw0KPlN1YmplY3Q6IFJlOiBbUEFU
Q0h2M10gZG1hZW5naW5lOiBmc2wtZWRtYTogZml4dXAgcmVnIG9mZnNldCBhbmQgaHcgUy9HDQo+
c3VwcG9ydCBpbiBiaWctZW5kaWFuIG1vZGVsDQo+DQo+SGksDQo+DQo+SmluZ2NoYW5nIEx1IHdy
b3RlOg0KPj4gVGhlIG9mZnNldCBvZiBhbGwgOC0vMTYtYml0IHJlZ2lzdGVyIGluIGJpZy1lbmRp
YW4gZURNQSBtb2RlbCBhcmUNCj5zL3JlZ2lzdGVyL3JlZ2lzdGVycy8NCj4NCj4+IHN3YXBwZWQg
aW4gYSAzMi1iaXQgc2l6ZSBvcHBvc2l0ZSB0aG9zZSBpbiB0aGUgbGl0dGxlLWVuZGlhbiBtb2Rl
bC4NCj4+DQo+PiBUaGUgaGFyZHdhcmUgU2NhdHRlci9HYXRoZXIgcmVxdWlyZXMgdGhlIHN1YnNl
cXVlbnQgVENEcyBpbiBtZW1vcnkgdG8NCj4+IGJlIGF1dG8gbG9hZGVkIHNob3VsZCByZXRhaW4g
bGl0dGxlIGVuZGlhbiBpbmRlcGVuZGVudCBvZiB0aGUgcmVnaXN0ZXINCj4+IGVuZGlhbiBtb2Rl
bCwgdGhlIGRtYSBlbmdpbmUgd2lsbCBkbyB0aGUgc3dhcCBpZiBuZWVkLg0KPj4NCj4+IFRoaXMg
cGF0Y2ggYWxzbyB1c2UgcmVndWxhciBhc3NpZ25tZW50IGZvciB0Y2QgdmFyaWFibGVzIHIvdyBp
bnN0ZWFkDQo+PiBvZiB3aXRoIGlvIGZ1bmN0aW9uIHByZXZpb3VzbHkgdGhhdCBtYXkgbm90IGFs
d2F5cyBiZSB0cnVlLg0KPj4NCj4+IFNpZ25lZC1vZmYtYnk6IEppbmdjaGFuZyBMdSA8amluZ2No
YW5nLmx1QGZyZWVzY2FsZS5jb20+DQo+PiAtLS0NCj4+IGNoYW5nZXMgaW4gdjM6DQo+PiAgdXNl
IHVuc2lnbmVkIGxvbmcgaW5zdGVhZCBvZiB1MzIgaW4gcmVnIG9mZnNldCBzd2FwIGNhc3QgdG8g
YXZvaWQNCj53YXJuaW5nLg0KPj4NCj4+IGNoYW5nZXMgaW4gdjI6DQo+PiAgc2ltcGxpZnkgcmVn
aXN0ZXIgb2Zmc2V0IHN3YXAgY2FsY3VsYXRpb24uDQo+PiAgdXNlIHJlZ3VsYXIgYXNzaWdubWVu
dCBmb3IgdGNkIHZhcmlhYmxlcyByL3cgaW5zdGVhZCBvZiBpbyBmdW5jdGlvbi4NCj4+DQo+PiAg
ZHJpdmVycy9kbWEvZnNsLWVkbWEuYyB8IDEwNg0KPj4gKysrKysrKysrKysrKysrKysrKysrKysr
KystLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KPj4gIDEgZmlsZSBjaGFuZ2VkLCA1NyBpbnNlcnRp
b25zKCspLCA0OSBkZWxldGlvbnMoLSkNCj4+DQo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9kbWEv
ZnNsLWVkbWEuYyBiL2RyaXZlcnMvZG1hL2ZzbC1lZG1hLmMgaW5kZXgNCj4+IDNjNTcxMWQuLjlj
YTU1ZWUgMTAwNjQ0DQo+PiAtLS0gYS9kcml2ZXJzL2RtYS9mc2wtZWRtYS5jDQo+PiArKysgYi9k
cml2ZXJzL2RtYS9mc2wtZWRtYS5jDQo+PiBAQCAtMTc3LDE2ICsxNzcsMTAgQEAgc3RydWN0IGZz
bF9lZG1hX2VuZ2luZSB7DQo+PiAgLyoNCj4+ICAgKiBSL1cgZnVuY3Rpb25zIGZvciBiaWctIG9y
IGxpdHRsZS1lbmRpYW4gcmVnaXN0ZXJzDQo+PiAgICogdGhlIGVETUEgY29udHJvbGxlcidzIGVu
ZGlhbiBpcyBpbmRlcGVuZGVudCBvZiB0aGUgQ1BVIGNvcmUncyBlbmRpYW4uDQo+PiArICogZm9y
IHRoZSBiaWctZW5kaWFuIElQIG1vZHVsZSwgdGhlIG9mZnNldCBmb3IgOC1iaXQgb3IgMTYtYml0
DQo+PiArIHJlZ2lzdGVyDQo+cy9mb3IvRm9yLw0KPg0KPj4gKyAqIHNob3VsZCBhbHNvIGJlIHN3
YXBwZWQgb3Bvc2l0ZSB0byB0aGF0IGluIGxpdHRsZS1lbmRpYW4gSVAuDQo+cy9vcG9zaXRlL29w
cG9zaXRlLw0KPg0KPlsuLi5dDQo+PiBAQCAtNDU5LDIwICs0NjAsMjcgQEAgc3RhdGljIHZvaWQg
ZmlsbF90Y2RfcGFyYW1zKHN0cnVjdCBmc2xfZWRtYV9lbmdpbmUNCj4qZWRtYSwNCj4+ICAJdTE2
IGNzciA9IDA7DQo+Pg0KPj4gIAkvKg0KPj4gLQkgKiBlRE1BIGhhcmR3YXJlIFNHcyByZXF1aXJl
IHRoZSBUQ0QgcGFyYW1ldGVycyBzdG9yZWQgaW4gbWVtb3J5DQo+PiAtCSAqIHRoZSBzYW1lIGVu
ZGlhbiBhcyB0aGUgZURNQSBtb2R1bGUgc28gdGhhdCB0aGV5IGNhbiBiZSBsb2FkZWQNCj4+IC0J
ICogYXV0b21hdGljYWxseSBieSB0aGUgZW5naW5lDQo+PiArCSAqIGVETUEgaGFyZHdhcmUgU0dz
IHJlcXVpcmVzIHRoZSBUQ0RzIHRvIGJlIGF1dG8gbG9hZGVkDQo+PiArCSAqIGluIHRoZSBsaXR0
bGUgZW5kaWFuIHdoZW52ZXIgdGhlIHJlZ2lzdGVyIGVuZGlhbiBtb2RlbCwNCj4iaW4gbGl0dGxl
IGVuZGlhbiB3aGF0ZXZlciB0aGUgcmVnaXN0ZXIgZW5kaWFuIG1vZGVsIg0KPg0KPj4gKwkgKiBT
byB3ZSBwdXQgdGhlIHZhbHVlIGluIGxpdHRsZSBlbmRpYW4gaW4gbWVtb3J5LCB3YWl0dGluZw0K
PnMvd2FpdHRpbmcvd2FpdGluZy8NCj4NCj4+ICsJICogZm9yIGZzbF9zZXRfdGNkX3BhcmFtcyBk
b2luZyB0aGUgc3dhcC4NCj5mc2xfc2V0X3RjZF9wYXJhbXMoKQ0KPg0KPg0KPg0KPkxvdGhhciBX
YcOfbWFubg0KPi0tDQpUaGFua3MsIEkgd2lsbCBhbWVuZCB0aGVtIGluIHRoZSBuZXh0IHZlcnNp
b24gcGF0Y2guDQoNCkJlc3QgUmVnYXJkcywNCkppbmdjaGFuZw0K
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jingchang Lu Sept. 25, 2014, 7:39 a.m. UTC | #4
Pi0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+RnJvbTogUnVzc2VsbCBLaW5nIC0gQVJNIExp
bnV4IFttYWlsdG86bGludXhAYXJtLmxpbnV4Lm9yZy51a10NCj5TZW50OiBXZWRuZXNkYXksIFNl
cHRlbWJlciAyNCwgMjAxNCA4OjA0IFBNDQo+VG86IExvdGhhciBXYcOfbWFubg0KPkNjOiBMdSBK
aW5nY2hhbmctQjM1MDgzOyB2aW5vZC5rb3VsQGludGVsLmNvbTsgYXJuZEBhcm5kYi5kZTsgbGlu
dXgtDQo+a2VybmVsQHZnZXIua2VybmVsLm9yZzsgZG1hZW5naW5lQHZnZXIua2VybmVsLm9yZzsg
bGludXgtYXJtLQ0KPmtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnDQo+U3ViamVjdDogUmU6IFtQ
QVRDSHYzXSBkbWFlbmdpbmU6IGZzbC1lZG1hOiBmaXh1cCByZWcgb2Zmc2V0IGFuZCBodyBTL0cN
Cj5zdXBwb3J0IGluIGJpZy1lbmRpYW4gbW9kZWwNCj4NCj5PbiBXZWQsIFNlcCAyNCwgMjAxNCBh
dCAwMTowNToxMFBNICswMjAwLCBMb3RoYXIgV2HDn21hbm4gd3JvdGU6DQo+PiBIaSwNCj4+DQo+
PiBKaW5nY2hhbmcgTHUgd3JvdGU6DQo+PiA+ICsJICogZURNQSBoYXJkd2FyZSBTR3MgcmVxdWly
ZXMgdGhlIFRDRHMgdG8gYmUgYXV0byBsb2FkZWQNCj4+ID4gKwkgKiBpbiB0aGUgbGl0dGxlIGVu
ZGlhbiB3aGVudmVyIHRoZSByZWdpc3RlciBlbmRpYW4gbW9kZWwsDQo+PiAiaW4gbGl0dGxlIGVu
ZGlhbiB3aGF0ZXZlciB0aGUgcmVnaXN0ZXIgZW5kaWFuIG1vZGVsIg0KPg0KPkV2ZW4gdGhhdCB0
b29rIHNldmVyYWwgcmVhZHMgdG8gd29yayBpdCBvdXQuDQo+DQo+CWVETUEgaGFyZHdhcmUgU0dz
IHJlcXVpcmUgdGhlIFRDRHMgdG8gYmUgc3RvcmVkIGluIGxpdHRsZSBlbmRpYW4NCj4JZm9ybWF0
IGlycmVzcGVjdGl2ZSBvZiB0aGUgcmVnaXN0ZXIgZW5kaWFuIG1vZGVsLg0KPg0KPmFuZCBJIHRo
aW5rIHRoYXQncyBhbGwgdGhhdCBuZWVkcyB0byBiZSBzYWlkIGhlcmUuDQo+DQo+SG93ZXZlciwg
YXMgSSByZWFsZHkgc3VnZ2VzdGVkLCBydW5uaW5nIHRoaXMgcnVkZHkgdGhpbmcgdGhyb3VnaCBz
cGFyc2UNCj53b3VsZCBiZSBhIC92ZXJ5LyBnb29kIGlkZWEsIGJlY2F1c2UgaXQnbGwgd2FybiB3
aXRoOg0KPg0KPisgICAgICAgdGNkLT5kYWRkciA9IGNwdV90b19sZTMyKGRzdCk7DQo+DQo+VGhl
IHJlYXNvbiBpdCdsbCB3YXJuIG9uIHRoYXQgaXMgYmVjYXVzZSBkYWRkciBpcyBub3QgZGVjbGFy
ZWQgd2l0aCBfX2xlMzIsDQo+ZXRjIC0gdGhlIHR5cGVzIHVzZWQgaW4gc3RydWN0IGZzbF9lZG1h
X2h3X3RjZCB0ZWxsIHNwYXJzZSB0aGF0IHRoZSB2YWx1ZXMNCj50byBiZSBzdG9yZWQgdGhlcmUg
YXJlIGluIF9ob3N0XyBlbmRpYW4gZm9ybWF0LCBidXQgdGhleSdyZSBiZWluZyBhc3NpZ25lZA0K
PmxpdHRsZSBlbmRpYW4gZm9ybWF0dGVkIGRhdGEuDQo+DQpJIGRpZG4ndCByZWFsaXplIHRoZSB0
eXBlIHdhcm5pbmcsIHRoZXkgaW5kZWVkIGV4aXN0LiBJIHdpbGwgdXNlIF9fbGUzMiBhbmQNCl9f
bGUxNiBmb3IgZnNsX2VkbWFfaHdfdGNkIHN0cnVjdCBtZW1iZXJzIGFzIGJlbG93Og0Kc3RydWN0
IGZzbF9lZG1hX2h3X3RjZCB7DQogICAgICAgIF9fbGUzMiAgc2FkZHI7DQogICAgICAgIF9fbGUx
NiAgc29mZjsNCiAgICAgICAgX19sZTE2ICBhdHRyOw0KICAgICAgICBfX2xlMzIgIG5ieXRlczsN
CiAgICAgICAgX19sZTMyICBzbGFzdDsNCiAgICAgICAgX19sZTMyICBkYWRkcjsNCiAgICAgICAg
X19sZTE2ICBkb2ZmOw0KICAgICAgICBfX2xlMTYgIGNpdGVyOw0KICAgICAgICBfX2xlMzIgIGRs
YXN0X3NnYTsNCiAgICAgICAgX19sZTE2ICBjc3I7DQogICAgICAgIF9fbGUxNiAgYml0ZXI7DQp9
Ow0KDQo+PiA+ICsJICogZm9yIGZzbF9zZXRfdGNkX3BhcmFtcyBkb2luZyB0aGUgc3dhcC4NCj4+
IGZzbF9zZXRfdGNkX3BhcmFtcygpDQo+DQo+VGhhdCdzIHRoZSB3cm9uZyBmdW5jdGlvbiBuYW1l
IGFueXdheS4gIEl0J3MgZnNsX2VkbWFfc2V0X3RjZF9wYXJhbXMoKS4NCj4NCj5Ib3dldmVyLCBs
ZXQncyBsb29rIGF0IHRoaXMgYSBsaXR0bGUgbW9yZToNCj4NCj4gICAgICAgIGZzbF9lZG1hX3Nl
dF90Y2RfcGFyYW1zKGZzbF9jaGFuLCB0Y2QtPnNhZGRyLCB0Y2QtPmRhZGRyLCB0Y2QtDQo+PmF0
dHIsDQo+ICAgICAgICAgICAgICAgICAgICAgICAgdGNkLT5zb2ZmLCB0Y2QtPm5ieXRlcywgdGNk
LT5zbGFzdCwgdGNkLT5jaXRlciwNCj4gICAgICAgICAgICAgICAgICAgICAgICB0Y2QtPmJpdGVy
LCB0Y2QtPmRvZmYsIHRjZC0+ZGxhc3Rfc2dhLCB0Y2QtPmNzcik7DQo+DQo+SXMgaXQgL3JlYWxs
eS8gYSBnb29kIGlkZWEgdG8gcmVhZCBhbGwgdGhhdCBkYXRhIG91dCBvZiB0aGUgc3RydWN0dXJl
LA0KPm9ubHkgdG8gdGhlbiBoYXZlIG1vc3Qgb2YgaXQgc2F2ZWQgaW50byB0aGUgc3RhY2ssIHdo
aWNoDQo+ZnNsX2VkbWFfc2V0X3RjZF9wYXJhbXMoKSB0aGVuIGhhcyB0byByZWFkIGJhY2sgb2Zm
IHRoZSBzdGFjayBhZ2Fpbj8NCj5XaXRoIHN0dWZmIGxpa2UgdGhpcywgb25lIGhhcyB0byB3b25k
ZXIgaWYgdGhlcmUgaXMgbXVjaCBjbHVlIGhvdyB0byB3cml0ZQ0KPm9wdGltYWwgQyBjb2RlIGlu
IHRoaXMgZHJpdmVyLg0KPg0KPlRoaXMgc2hvdWxkIGJlIHBhc3NpbmcgdGhlIHRjZCBzdHJ1Y3R1
cmUgaW50byBmc2xfZWRtYV9zZXRfdGNkX3BhcmFtcygpLg0KPg0KPk5vdywgdGhpcyBmdW5jdGlv
biBjb250YWlucyB0aGlzIGNvbW1lbnQ6DQo+DQo+ICAgICAgICAvKg0KPiAgICAgICAgICogVENE
IHBhcmFtZXRlcnMgaGF2ZSBiZWVuIHN3YXBwZWQgaW4gZmlsbF90Y2RfcGFyYW1zKCksDQo+ICAg
ICAgICAgKiBzbyBqdXN0IHdyaXRlIHRoZW0gdG8gcmVnaXN0ZXJzIGluIHRoZSBjcHUgZW5kaWFu
IGhlcmUNCj4gICAgICAgICAqLw0KPg0KPldoaWNoIGlzIGFsbW9zdCByZWFzb25hYmxlLCBidXQg
bGV0J3MgdXBkYXRlIGl0Og0KPg0KPglUQ0QgcGFyYW1ldGVycyBhcmUgc3RvcmVkIGluIHN0cnVj
dCBmc2xfZWRtYV9od190Y2QgaW4gbGl0dGxlDQo+CWVuZGlhbiBmb3JtYXQuICBIb3dldmVyLCB3
ZSBuZWVkIHRvIGxvYWQgdGhlIHJlZ2lzdGVycyBpbg0KPgk8aW5zZXJ0IGFwcHJvcHJpYXRlIGVu
ZGlhbm5lc3MgLSBiaWd8bGl0dGxlfGNwdT4gZW5kaWFuLg0KPg0KPk5vdywgcmVtZW1iZXIgdGhh
dCB3cml0ZWwoKSBhbmQgZnJpZW5kcyBleHBlY3QgbmF0aXZlIENQVSBlbmRpYW4gZm9ybWF0dGVk
DQo+ZGF0YSAoYW5kIHllcywgc3BhcnNlIGNoZWNrcyB0aGlzIHRvbykgc28gdGhhdCBuZWVkcyB0
byBiZSBjb25zaWRlcmVkIG1vcmUuDQo+DQo+TGFzdGx5LCB0aGUgZHJpdmVyIHNlZW1zIHRvIGJl
IGEgdG90YWwgbWVzcyBvZiBhY2Nlc3NvcnMuICBJbiBzb21lIHBsYWNlcw0KPml0IHVzZXMgaW97
cmVhZCx3cml0ZX0qLCBpbiBvdGhlciBwbGFjZXMsIGl0IHVzZXMgcGxhaW4ge3JlYWQsd3JpdGV9
Ki4gIEl0DQo+c2hvdWxkIHVzZSBlaXRoZXIgb25lIHNldCBvciB0aGUgb3RoZXIgc2V0LCBhbmQg
bm90IG1peCB0aGVzZSB0d28uDQo+DQo+SSBqdXN0IHNwb3R0ZWQgdGhpcyBiYWRseSBmb3JtYXR0
ZWQgY29kZSB0b286DQo+DQo+ICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZnNsX2Rlc2MtPm5fdGNk
czsgaSsrKQ0KPiAgICAgICAgICAgICAgICAgICAgICAgIGRtYV9wb29sX2ZyZWUoZnNsX2Rlc2Mt
PmVjaGFuLT50Y2RfcG9vbCwNCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgZnNsX2Rlc2MtPnRjZFtpXS52dGNkLA0KPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICBmc2xfZGVzYy0+dGNkW2ldLnB0Y2QpOyAuLi4NCj4gICAgICAgICAgICAgICAg
ZWRtYV93cml0ZWIoZnNsX2NoYW4tPmVkbWEsDQo+ICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICBFRE1BTVVYX0NIQ0ZHX0VOQkwgfA0KPkVETUFNVVhfQ0hDRkdfU09VUkNFKHNsb3QpLA0K
PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV4YWRkciArIGNoX29mZik7DQo+DQo+
LS0NClRoYW5rcywgSSB3aWxsIHVzZSB0aGUgdGNkIHBvaW50ZXIgaW5zdGVhZC4gQW5kIEkgd2ls
bCB1c2Ugb25lIHIvdyBzZXQuDQoNCkJlc3QgUmVnYXJkcywNCkppbmdjaGFuZw0K
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index 3c5711d..9ca55ee 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -177,16 +177,10 @@  struct fsl_edma_engine {
 /*
  * R/W functions for big- or little-endian registers
  * the eDMA controller's endian is independent of the CPU core's endian.
+ * for the big-endian IP module, the offset for 8-bit or 16-bit register
+ * should also be swapped oposite to that in little-endian IP.
  */
 
-static u16 edma_readw(struct fsl_edma_engine *edma, void __iomem *addr)
-{
-	if (edma->big_endian)
-		return ioread16be(addr);
-	else
-		return ioread16(addr);
-}
-
 static u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
 {
 	if (edma->big_endian)
@@ -197,13 +191,18 @@  static u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
 
 static void edma_writeb(struct fsl_edma_engine *edma, u8 val, void __iomem *addr)
 {
-	iowrite8(val, addr);
+	/* swap the reg offset for these in big-endian mode */
+	if (edma->big_endian)
+		iowrite8(val, (void __iomem *)((unsigned long)addr ^ 0x3));
+	else
+		iowrite8(val, addr);
 }
 
 static void edma_writew(struct fsl_edma_engine *edma, u16 val, void __iomem *addr)
 {
+	/* swap the reg offset for these in big-endian mode */
 	if (edma->big_endian)
-		iowrite16be(val, addr);
+		iowrite16be(val, (void __iomem *)((unsigned long)addr ^ 0x2));
 	else
 		iowrite16(val, addr);
 }
@@ -256,11 +255,10 @@  static void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
 	muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux];
 
 	if (enable)
-		edma_writeb(fsl_chan->edma,
-				EDMAMUX_CHCFG_ENBL | EDMAMUX_CHCFG_SOURCE(slot),
+		writeb(EDMAMUX_CHCFG_ENBL | EDMAMUX_CHCFG_SOURCE(slot),
 				muxaddr + ch_off);
 	else
-		edma_writeb(fsl_chan->edma, EDMAMUX_CHCFG_DIS, muxaddr + ch_off);
+		writeb(EDMAMUX_CHCFG_DIS, muxaddr + ch_off);
 }
 
 static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth addr_width)
@@ -363,8 +361,8 @@  static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
 
 	/* calculate the total size in this desc */
 	for (len = i = 0; i < fsl_chan->edesc->n_tcds; i++)
-		len += edma_readl(fsl_chan->edma, &(edesc->tcd[i].vtcd->nbytes))
-			* edma_readw(fsl_chan->edma, &(edesc->tcd[i].vtcd->biter));
+		len += le32_to_cpu(edesc->tcd[i].vtcd->nbytes)
+			* le16_to_cpu(edesc->tcd[i].vtcd->biter);
 
 	if (!in_progress)
 		return len;
@@ -376,14 +374,12 @@  static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
 
 	/* figure out the finished and calculate the residue */
 	for (i = 0; i < fsl_chan->edesc->n_tcds; i++) {
-		size = edma_readl(fsl_chan->edma, &(edesc->tcd[i].vtcd->nbytes))
-			* edma_readw(fsl_chan->edma, &(edesc->tcd[i].vtcd->biter));
+		size = le32_to_cpu(edesc->tcd[i].vtcd->nbytes)
+			* le16_to_cpu(edesc->tcd[i].vtcd->biter);
 		if (dir == DMA_MEM_TO_DEV)
-			dma_addr = edma_readl(fsl_chan->edma,
-					&(edesc->tcd[i].vtcd->saddr));
+			dma_addr = le32_to_cpu(edesc->tcd[i].vtcd->saddr);
 		else
-			dma_addr = edma_readl(fsl_chan->edma,
-					&(edesc->tcd[i].vtcd->daddr));
+			dma_addr = le32_to_cpu(edesc->tcd[i].vtcd->daddr);
 
 		len -= size;
 		if (cur_addr > dma_addr && cur_addr < dma_addr + size) {
@@ -433,21 +429,26 @@  static void fsl_edma_set_tcd_params(struct fsl_edma_chan *fsl_chan,
 	u32 ch = fsl_chan->vchan.chan.chan_id;
 
 	/*
-	 * TCD parameters have been swapped in fill_tcd_params(),
-	 * so just write them to registers in the cpu endian here
+	 * TCD parameters should be swapped according the eDMA
+	 * engine requirement.
 	 */
-	writew(0, addr + EDMA_TCD_CSR(ch));
-	writel(src, addr + EDMA_TCD_SADDR(ch));
-	writel(dst, addr + EDMA_TCD_DADDR(ch));
-	writew(attr, addr + EDMA_TCD_ATTR(ch));
-	writew(soff, addr + EDMA_TCD_SOFF(ch));
-	writel(nbytes, addr + EDMA_TCD_NBYTES(ch));
-	writel(slast, addr + EDMA_TCD_SLAST(ch));
-	writew(citer, addr + EDMA_TCD_CITER(ch));
-	writew(biter, addr + EDMA_TCD_BITER(ch));
-	writew(doff, addr + EDMA_TCD_DOFF(ch));
-	writel(dlast_sga, addr + EDMA_TCD_DLAST_SGA(ch));
-	writew(csr, addr + EDMA_TCD_CSR(ch));
+	edma_writew(fsl_chan->edma, 0, addr + EDMA_TCD_CSR(ch));
+	edma_writel(fsl_chan->edma, src, addr + EDMA_TCD_SADDR(ch));
+	edma_writel(fsl_chan->edma, dst, addr + EDMA_TCD_DADDR(ch));
+
+	edma_writew(fsl_chan->edma, attr, addr + EDMA_TCD_ATTR(ch));
+	edma_writew(fsl_chan->edma, soff, addr + EDMA_TCD_SOFF(ch));
+
+	edma_writel(fsl_chan->edma, nbytes, addr + EDMA_TCD_NBYTES(ch));
+	edma_writel(fsl_chan->edma, slast, addr + EDMA_TCD_SLAST(ch));
+
+	edma_writew(fsl_chan->edma, citer, addr + EDMA_TCD_CITER(ch));
+	edma_writew(fsl_chan->edma, biter, addr + EDMA_TCD_BITER(ch));
+	edma_writew(fsl_chan->edma, doff, addr + EDMA_TCD_DOFF(ch));
+
+	edma_writel(fsl_chan->edma, dlast_sga, addr + EDMA_TCD_DLAST_SGA(ch));
+
+	edma_writew(fsl_chan->edma, csr, addr + EDMA_TCD_CSR(ch));
 }
 
 static void fill_tcd_params(struct fsl_edma_engine *edma,
@@ -459,20 +460,27 @@  static void fill_tcd_params(struct fsl_edma_engine *edma,
 	u16 csr = 0;
 
 	/*
-	 * eDMA hardware SGs require the TCD parameters stored in memory
-	 * the same endian as the eDMA module so that they can be loaded
-	 * automatically by the engine
+	 * eDMA hardware SGs requires the TCDs to be auto loaded
+	 * in the little endian whenver the register endian model,
+	 * So we put the value in little endian in memory, waitting
+	 * for fsl_set_tcd_params doing the swap.
 	 */
-	edma_writel(edma, src, &(tcd->saddr));
-	edma_writel(edma, dst, &(tcd->daddr));
-	edma_writew(edma, attr, &(tcd->attr));
-	edma_writew(edma, EDMA_TCD_SOFF_SOFF(soff), &(tcd->soff));
-	edma_writel(edma, EDMA_TCD_NBYTES_NBYTES(nbytes), &(tcd->nbytes));
-	edma_writel(edma, EDMA_TCD_SLAST_SLAST(slast), &(tcd->slast));
-	edma_writew(edma, EDMA_TCD_CITER_CITER(citer), &(tcd->citer));
-	edma_writew(edma, EDMA_TCD_DOFF_DOFF(doff), &(tcd->doff));
-	edma_writel(edma, EDMA_TCD_DLAST_SGA_DLAST_SGA(dlast_sga), &(tcd->dlast_sga));
-	edma_writew(edma, EDMA_TCD_BITER_BITER(biter), &(tcd->biter));
+	tcd->saddr = cpu_to_le32(src);
+	tcd->daddr = cpu_to_le32(dst);
+
+	tcd->attr = cpu_to_le16(attr);
+
+	tcd->soff = cpu_to_le16(EDMA_TCD_SOFF_SOFF(soff));
+
+	tcd->nbytes = cpu_to_le32(EDMA_TCD_NBYTES_NBYTES(nbytes));
+	tcd->slast = cpu_to_le32(EDMA_TCD_SLAST_SLAST(slast));
+
+	tcd->citer = cpu_to_le16(EDMA_TCD_CITER_CITER(citer));
+	tcd->doff = cpu_to_le16(EDMA_TCD_DOFF_DOFF(doff));
+
+	tcd->dlast_sga = cpu_to_le32(EDMA_TCD_DLAST_SGA_DLAST_SGA(dlast_sga));
+
+	tcd->biter = cpu_to_le16(EDMA_TCD_BITER_BITER(biter));
 	if (major_int)
 		csr |= EDMA_TCD_CSR_INT_MAJOR;
 
@@ -482,7 +490,7 @@  static void fill_tcd_params(struct fsl_edma_engine *edma,
 	if (enable_sg)
 		csr |= EDMA_TCD_CSR_E_SG;
 
-	edma_writew(edma, csr, &(tcd->csr));
+	tcd->csr = cpu_to_le16(csr);
 }
 
 static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan,