Message ID | 1396901229-29117-9-git-send-email-ben.dooks@codethink.co.uk (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
On 04/08/2014 12:07 AM, Ben Dooks wrote: > Add support for building shdma internal data from the device tree to allow > converting the driver to be device tree enabled. > It includes a helper for the of case to build the internal data used to > select and filter out the DMA channels from the ID information in the > device tree. Also updates the documentation for the DT case. > Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> > --- > Documentation/devicetree/bindings/dma/shdma.txt | 24 +++++ > drivers/dma/sh/shdma-of.c | 134 ++++++++++++++++++++++++ > drivers/dma/sh/shdma.h | 20 ++++ > include/dt-bindings/dma/shdma.h | 45 ++++++++ > 4 files changed, 223 insertions(+) > create mode 100644 include/dt-bindings/dma/shdma.h > diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt > index 2a3f3b8..7d9e7bd 100644 > --- a/Documentation/devicetree/bindings/dma/shdma.txt > +++ b/Documentation/devicetree/bindings/dma/shdma.txt > @@ -15,6 +15,12 @@ Required properties: > - compatible: should be "renesas,shdma-mux" > - #dma-cells: should be <1>, see "dmas" property below > > +New properites, required for renesas,dma-r8a7790. > +- reneasa,slaves: A list of DMA channel MID/RID and the configuration to s/reneasa/renesas/ > + go with them. These pairs are in the form of: > + < mid+rid configuration> Space after < probably not needed. > @@ -70,6 +77,23 @@ Example: > }; > }; > > +For r8a7790, the following is an example of using the reneasas,slaves to s/reneasas/renesas/ [...] > diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c > index 06473a0..386fd9e 100644 > --- a/drivers/dma/sh/shdma-of.c > +++ b/drivers/dma/sh/shdma-of.c > @@ -3,12 +3,15 @@ > * > * Copyright (C) 2013 Renesas Electronics Inc. > * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> > + * Copyright (c) 2014 Codethink Limited > + * Ben Dooks <ben.dooks@codethink.co.uk> > * > * This is free software; you can redistribute it and/or modify > * it under the terms of version 2 of the GNU General Public License as > * published by the Free Software Foundation. > */ > > +#include <linux/slab.h> I think the #include's are sorted alphabetically in this file. > #include <linux/dmaengine.h> > #include <linux/module.h> > #include <linux/of.h> > @@ -16,9 +19,37 @@ > #include <linux/of_platform.h> > #include <linux/platform_device.h> > #include <linux/shdma-base.h> > +#include <linux/sh_dma.h> > + > +#include <dt-bindings/dma/shdma.h> > > #define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan) > > +#include "shdma-arm.h" > + > +static const unsigned int arm_dma_ts_shift[] = SH_DMAE_TS_SHIFT; > + > +static struct sh_dmae_pdata arm_dmae_info = { > + .ts_low_shift = SHDMA_ARM_TS_LOW_SHIFT, > + .ts_low_mask = SHDMA_ARM_TS_LOW_BIT << SHDMA_ARM_TS_LOW_SHIFT, > + .ts_high_shift = SHDMA_ARM_TS_HI_SHIFT, > + .ts_high_mask = SHDMA_ARM_TS_HI_BIT << SHDMA_ARM_TS_HI_SHIFT, > + .ts_shift = arm_dma_ts_shift, > + .ts_shift_num = ARRAY_SIZE(arm_dma_ts_shift), > + .dmaor_init = DMAOR_DME, > + .chclr_present = 1, > + .chclr_bitwise = 1, > +}; > + > +struct sh_dmae_of_info shdma_arm_info = { > + .pdata_template = &arm_dmae_info, > + .channel_offset = 0x8000-0x20, Spaces needed around -, so that the code is at least consistent. > + .channel_stride = 0x80, > + .offset = 0x0, > + .dmars = 0x40, > + .chclr_offset = 0x80, > +}; > + > static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec, > struct of_dma *ofdma) > { > @@ -40,6 +71,109 @@ static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec, > return chan; > } > > +const struct sh_dmae_pdata * > +sh_dma_probe_of(struct platform_device *pdev, const struct of_device_id *ofmatch) > +{ [...] > + /* look in current, or parent node for the slave mappings */ > + prop = of_find_property(np, "renesas,slaves", &len); > + if (!prop) > + prop = of_find_property(np->parent, "renesas,slaves", &len); > + Empty line not needed here. > + if (prop) { > + struct sh_dmae_slave_config *slaves; > + int nr_slaves = len / (sizeof(u32) * 3); > + const __be32 *of_ptr; > + u32 of_idx; > + [...] > diff --git a/include/dt-bindings/dma/shdma.h b/include/dt-bindings/dma/shdma.h > new file mode 100644 > index 0000000..0c8fc9e > --- /dev/null > +++ b/include/dt-bindings/dma/shdma.h > @@ -0,0 +1,45 @@ > +/* DMA binding definitions for SH-DMAC engines. > + * > + * Moved from sh_dma.h to share with device tree by Ben Dooks. > + * Orignal code from: > + * shdma.h: Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> > + * shdma-arm.h: Copyright (C) 2013 Renesas Electronics, Inc. Hm, you're adding the new code, not moving it, as it seems from this patch... [...] WBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
T24gTW9uLCAyMDE0LTA0LTA3IGF0IDIxOjA3ICswMTAwLCBCZW4gRG9va3Mgd3JvdGU6DQo+IEFk ZCBzdXBwb3J0IGZvciBidWlsZGluZyBzaGRtYSBpbnRlcm5hbCBkYXRhIGZyb20gdGhlIGRldmlj ZSB0cmVlIHRvIGFsbG93DQo+IGNvbnZlcnRpbmcgdGhlIGRyaXZlciB0byBiZSBkZXZpY2UgdHJl ZSBlbmFibGVkLg0KPiANCj4gSXQgaW5jbHVkZXMgYSBoZWxwZXIgZm9yIHRoZSBvZiBjYXNlIHRv IGJ1aWxkIHRoZSBpbnRlcm5hbCBkYXRhIHVzZWQgdG8NCj4gc2VsZWN0IGFuZCBmaWx0ZXIgb3V0 IHRoZSBETUEgY2hhbm5lbHMgZnJvbSB0aGUgSUQgaW5mb3JtYXRpb24gaW4gdGhlDQo+IGRldmlj ZSB0cmVlLiBBbHNvIHVwZGF0ZXMgdGhlIGRvY3VtZW50YXRpb24gZm9yIHRoZSBEVCBjYXNlLg0K DQoNCkZldyBtaW5vciBjb21tZW50cyBiZWxvdy4NCg0KPiAtLS0gYS9kcml2ZXJzL2RtYS9zaC9z aGRtYS1vZi5jDQo+ICsrKyBiL2RyaXZlcnMvZG1hL3NoL3NoZG1hLW9mLmMNCg0KDQo+IEBAIC00 MCw2ICs3MSwxMDkgQEAgc3RhdGljIHN0cnVjdCBkbWFfY2hhbiAqc2hkbWFfb2ZfeGxhdGUoc3Ry dWN0IG9mX3BoYW5kbGVfYXJncyAqZG1hX3NwZWMsDQo+ICAJcmV0dXJuIGNoYW47DQo+ICB9DQo+ ICANCj4gK2NvbnN0IHN0cnVjdCBzaF9kbWFlX3BkYXRhICoNCj4gK3NoX2RtYV9wcm9iZV9vZihz dHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2LCBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkICpv Zm1hdGNoKQ0KPiArew0KPiArCWNvbnN0IHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBwZGV2LT5k ZXYub2Zfbm9kZTsNCj4gKwljb25zdCBzdHJ1Y3Qgc2hfZG1hZV9vZl9pbmZvICpvZmluZjsNCj4g KwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ZGV2Ow0KPiArCXN0cnVjdCBzaF9kbWFlX3Bk YXRhICpwZGF0YTsNCj4gKwlzdHJ1Y3Qgc2hfZG1hZV9jaGFubmVsICpjaGFuOw0KPiArCXN0cnVj dCBwcm9wZXJ0eSAqcHJvcDsNCj4gKwl1MzIgbnJfY2hhbjsNCj4gKwl1bnNpZ25lZCBjaDsNCj4g KwlpbnQgcmV0Ow0KPiArCWludCBsZW47DQo+ICsNCj4gKwlpZiAoIW9mbWF0Y2gpDQo+ICsJCXJl dHVybiBOVUxMOw0KPiArDQo+ICsJb2ZpbmYgPSBvZm1hdGNoLT5kYXRhOw0KPiArDQo+ICsJcGRh dGEgPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2Yoc3RydWN0IHNoX2RtYWVfcGRhdGEpLCBHRlBf S0VSTkVMKTsNCg0Kc2l6ZW9mKCpwZGF0YSkgPw0KDQo+ICsJaWYgKCFwZGF0YSkgew0KPiArCQlk ZXZfZXJyKGRldiwgImZhaWxlZCB0byBtYWtlIHBsYXRmb3JtIGRhdGFcbiIpOw0KPiArCQlyZXR1 cm4gTlVMTDsNCj4gKwl9DQo+ICsNCj4gKwkqcGRhdGEgPSAqb2ZpbmYtPnBkYXRhX3RlbXBsYXRl OwkvKiBjb3B5IGluIHRlbXBsYXRlIGZpcnN0ICovDQo+ICsNCj4gKwlyZXQgPSBvZl9wcm9wZXJ0 eV9yZWFkX3UzMihucCwgImRtYS1jaGFubmVscyIsICZucl9jaGFuKTsNCj4gKwlpZiAocmV0IDwg MCkgew0KPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBnZXQgbnVtYmVyIG9mIGNoYW5uZWxz XG4iKTsNCj4gKwkJcmV0dXJuIE5VTEw7DQo+ICsJfQ0KPiArDQo+ICsJY2hhbiA9IGRldm1fa3ph bGxvYyhkZXYsIG5yX2NoYW4gKiBzaXplb2Yoc3RydWN0IHNoX2RtYWVfY2hhbm5lbCksDQo+ICsJ CQkgICAgR0ZQX0tFUk5FTCk7DQoNCmRldm1fa2NhbGxvYygpDQoNCj4gKwlpZiAoIWNoYW4pIHsN Cj4gKwkJZGV2X2VycihkZXYsICJjYW5ub3QgYWxsb2NhdGUgJWQgY2hhbm5lbHNcbiIsIG5yX2No YW4pOw0KPiArCQlyZXR1cm4gTlVMTDsNCj4gKwl9DQo+ICsNCj4gKwlwZGF0YS0+Y2hhbm5lbCA9 IGNoYW47DQo+ICsJcGRhdGEtPmNoYW5uZWxfbnVtID0gbnJfY2hhbjsNCj4gKw0KPiArCWRldl9k YmcoZGV2LCAiJWQgZG1hIGNoYW5uZWxzIGFsbG9jYXRlZFxuIiwgbnJfY2hhbik7DQo+ICsNCj4g Kwlmb3IgKGNoID0gMDsgY2ggPCBucl9jaGFuOyBjaCsrKSB7DQo+ICsJCXN0cnVjdCBzaF9kbWFl X2NoYW5uZWwgKmNwID0gY2hhbiArIGNoOw0KPiArCQl1MzIgYmFzZSA9IG9maW5mLT5jaGFubmVs X29mZnNldCArIG9maW5mLT5jaGFubmVsX3N0cmlkZSAqIGNoOw0KPiArDQo+ICsJCWNwLT5vZmZz ZXQgPSBiYXNlICsgb2ZpbmYtPm9mZnNldDsNCj4gKwkJY3AtPmRtYXJzID0gYmFzZSArIG9maW5m LT5kbWFyczsNCj4gKwkJY3AtPmNoY2xyX2JpdCA9IGNoOw0KPiArCQljcC0+Y2hjbHJfb2Zmc2V0 ID0gb2ZpbmYtPmNoY2xyX29mZnNldDsNCj4gKw0KPiArCQlkZXZfZGJnKGRldiwgImNoICVkOiBv ZmYgJTA4eCwgZG1hcnMgJTA4eCwgYml0ICVkLCBvZmYgJWRcbiIsDQo+ICsJCQljaCwgY3AtPm9m ZnNldCwgY3AtPmRtYXJzLA0KPiArCQkJY3AtPmNoY2xyX2JpdCwgY3AtPmNoY2xyX29mZnNldCk7 DQo+ICsJfQ0KPiArDQo+ICsJLyogbG9vayBpbiBjdXJyZW50LCBvciBwYXJlbnQgbm9kZSBmb3Ig dGhlIHNsYXZlIG1hcHBpbmdzICovDQo+ICsJcHJvcCA9IG9mX2ZpbmRfcHJvcGVydHkobnAsICJy ZW5lc2FzLHNsYXZlcyIsICZsZW4pOw0KPiArCWlmICghcHJvcCkNCj4gKwkJcHJvcCA9IG9mX2Zp bmRfcHJvcGVydHkobnAtPnBhcmVudCwgInJlbmVzYXMsc2xhdmVzIiwgJmxlbik7DQo+ICsNCj4g KwlpZiAocHJvcCkgew0KPiArCQlzdHJ1Y3Qgc2hfZG1hZV9zbGF2ZV9jb25maWcgKnNsYXZlczsN Cj4gKwkJaW50IG5yX3NsYXZlcyA9IGxlbiAvIChzaXplb2YodTMyKSAqIDMpOw0KPiArCQljb25z dCBfX2JlMzIgKm9mX3B0cjsNCj4gKwkJdTMyIG9mX2lkeDsNCj4gKw0KPiArCQlzbGF2ZXMgPSBk ZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKnNsYXZlcykgKiBucl9zbGF2ZXMsDQo+ICsJCQkJICAg ICAgR0ZQX0tFUk5FTCk7DQoNCmRldm1fa2NhbGxvYygpDQoNCj4gKwkJaWYgKCFzbGF2ZXMpIHsN Cj4gKwkJCWRldl9lcnIoZGV2LCAiY2Fubm90IGFsbG9jYXRlICVkIHNsYXZlc1xuIiwgbnJfc2xh dmVzKTsNCj4gKwkJCXJldHVybiBOVUxMOw0KPiArCQl9DQo+ICsNCj4gKwkJcGRhdGEtPnNsYXZl ID0gc2xhdmVzOw0KPiArCQlwZGF0YS0+c2xhdmVfbnVtID0gbnJfc2xhdmVzOw0KPiArCQlvZl9p ZHggPSAwOw0KPiArCQlvZl9wdHIgPSBOVUxMOw0KPiArDQo+ICsJCWRldl9kYmcoZGV2LCAiYnVp bGRpbmcgJWQgc2xhdmVzXG4iLCBucl9zbGF2ZXMpOw0KPiArDQo+ICsJCWZvciAoOyBucl9zbGF2 ZXMgPiAwOyBucl9zbGF2ZXMtLSwgc2xhdmVzKyspIHsNCj4gKwkJCW9mX3B0cj0gb2ZfcHJvcF9u ZXh0X3UzMihwcm9wLCBvZl9wdHIsICZvZl9pZHgpOw0KPiArCQkJc2xhdmVzLT5taWRfcmlkID0g YmUzMl90b19jcHUoKm9mX3B0cik7DQo+ICsJCQlzbGF2ZXMtPnNsYXZlX2lkID0gc2xhdmVzLT5t aWRfcmlkOw0KPiArDQo+ICsJCQlvZl9wdHI9IG9mX3Byb3BfbmV4dF91MzIocHJvcCwgb2ZfcHRy LCAmb2ZfaWR4KTsNCj4gKwkJCXNsYXZlcy0+Y2hjciA9IGJlMzJfdG9fY3B1KCpvZl9wdHIpOw0K PiArDQo+ICsJCQlkZXZfZGJnKGRldiwgInNsYXZlOiBpZCAlMDJ4LCBjaGNyICUwOHgsIGFkZHIg JTA4eFxuIiwNCj4gKwkJCQlzbGF2ZXMtPm1pZF9yaWQsIHNsYXZlcy0+Y2hjciwgc2xhdmVzLT5h ZGRyKTsNCj4gKwkJfQ0KPiArCX0gZWxzZSB7DQo+ICsJCWRldl93YXJuKGRldiwgImRpZCBub3Qg ZmluZCBhbnkgc2xhdmUgaW5mb3JtYXRpb25cbiIpOw0KPiArCX0NCj4gKw0KPiArCXBkZXYtPmRl di5wbGF0Zm9ybV9kYXRhID0gcGRhdGE7DQo+ICsJcmV0dXJuIHBkYXRhOw0KPiArfTsNCg0KDQoN Ci0tIA0KQW5keSBTaGV2Y2hlbmtvIDxhbmRyaXkuc2hldmNoZW5rb0BpbnRlbC5jb20+DQpJbnRl bCBGaW5sYW5kIE95DQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KSW50ZWwgRmlubGFuZCBPeQpSZWdpc3RlcmVkIEFk ZHJlc3M6IFBMIDI4MSwgMDAxODEgSGVsc2lua2kgCkJ1c2luZXNzIElkZW50aXR5IENvZGU6IDAz NTc2MDYgLSA0IApEb21pY2lsZWQgaW4gSGVsc2lua2kgCgpUaGlzIGUtbWFpbCBhbmQgYW55IGF0 dGFjaG1lbnRzIG1heSBjb250YWluIGNvbmZpZGVudGlhbCBtYXRlcmlhbCBmb3IKdGhlIHNvbGUg dXNlIG9mIHRoZSBpbnRlbmRlZCByZWNpcGllbnQocykuIEFueSByZXZpZXcgb3IgZGlzdHJpYnV0 aW9uCmJ5IG90aGVycyBpcyBzdHJpY3RseSBwcm9oaWJpdGVkLiBJZiB5b3UgYXJlIG5vdCB0aGUg aW50ZW5kZWQKcmVjaXBpZW50LCBwbGVhc2UgY29udGFjdCB0aGUgc2VuZGVyIGFuZCBkZWxldGUg YWxsIGNvcGllcy4K -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 08/04/14 09:04, Shevchenko, Andriy wrote: > On Mon, 2014-04-07 at 21:07 +0100, Ben Dooks wrote: >> Add support for building shdma internal data from the device tree to allow >> converting the driver to be device tree enabled. >> >> It includes a helper for the of case to build the internal data used to >> select and filter out the DMA channels from the ID information in the >> device tree. Also updates the documentation for the DT case. > > > Few minor comments below. > >> --- a/drivers/dma/sh/shdma-of.c >> +++ b/drivers/dma/sh/shdma-of.c > > >> @@ -40,6 +71,109 @@ static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec, >> return chan; >> } >> >> +const struct sh_dmae_pdata * >> +sh_dma_probe_of(struct platform_device *pdev, const struct of_device_id *ofmatch) >> +{ >> + const struct device_node *np = pdev->dev.of_node; >> + const struct sh_dmae_of_info *ofinf; >> + struct device *dev = &pdev->dev; >> + struct sh_dmae_pdata *pdata; >> + struct sh_dmae_channel *chan; >> + struct property *prop; >> + u32 nr_chan; >> + unsigned ch; >> + int ret; >> + int len; >> + >> + if (!ofmatch) >> + return NULL; >> + >> + ofinf = ofmatch->data; >> + >> + pdata = devm_kzalloc(dev, sizeof(struct sh_dmae_pdata), GFP_KERNEL); > > sizeof(*pdata) ? I will think on this one. >> + if (!pdata) { >> + dev_err(dev, "failed to make platform data\n"); >> + return NULL; >> + } >> + >> + *pdata = *ofinf->pdata_template; /* copy in template first */ >> + >> + ret = of_property_read_u32(np, "dma-channels", &nr_chan); >> + if (ret < 0) { >> + dev_err(dev, "failed to get number of channels\n"); >> + return NULL; >> + } >> + >> + chan = devm_kzalloc(dev, nr_chan * sizeof(struct sh_dmae_channel), >> + GFP_KERNEL); > > devm_kcalloc() Thanks.
Hi Ben, thank you for the patch. On Monday 07 April 2014 21:07:08 Ben Dooks wrote: > Add support for building shdma internal data from the device tree to allow > converting the driver to be device tree enabled. > > It includes a helper for the of case to build the internal data used to > select and filter out the DMA channels from the ID information in the > device tree. Also updates the documentation for the DT case. > > Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> > --- > Documentation/devicetree/bindings/dma/shdma.txt | 24 +++++ > drivers/dma/sh/shdma-of.c | 134 +++++++++++++++++++++ > drivers/dma/sh/shdma.h | 20 ++++ > include/dt-bindings/dma/shdma.h | 45 ++++++++ > 4 files changed, 223 insertions(+) > create mode 100644 include/dt-bindings/dma/shdma.h > > diff --git a/Documentation/devicetree/bindings/dma/shdma.txt > b/Documentation/devicetree/bindings/dma/shdma.txt index 2a3f3b8..7d9e7bd > 100644 > --- a/Documentation/devicetree/bindings/dma/shdma.txt > +++ b/Documentation/devicetree/bindings/dma/shdma.txt > @@ -15,6 +15,12 @@ Required properties: > - compatible: should be "renesas,shdma-mux" > - #dma-cells: should be <1>, see "dmas" property below > > +New properites, required for renesas,dma-r8a7790. s/properites/properties/ > +- reneasa,slaves: A list of DMA channel MID/RID and the configuration to s/reneasa/renesas/ > + go with them. These pairs are in the form of: > + < mid+rid configuration> The description is pretty terse. Just reading it I don't know what slaves need to be listed, what an MID or RID is, how "mid+rid" combines the MID and RID exactly, and what configuration can be specified. I believe a more detailed description is needed. > + > + > Optional properties (currently unused): > - dma-channels: number of DMA channels > - dma-requests: number of DMA request signals > @@ -25,6 +31,7 @@ Required properties: > - compatible: should be of the form "renesas,shdma-<soc>", where <soc> > should be replaced with the desired SoC model, e.g. > "renesas,shdma-r8a73a4" for the system DMAC on r8a73a4 SoC > + "renesas,dma-r8a7790" for the DMAC on the R8A7790. > > Example: > dmac: dma-multiplexer@0 { > @@ -70,6 +77,23 @@ Example: > }; > }; > > +For r8a7790, the following is an example of using the reneasas,slaves to > +configure the slave channels on the controller: > + > + dma0: dma-mux@0 { > + compatible = "renesas,shdma-mux"; > + #dma-cells = <1>; > + dma-channels = <20>; > + dma-requests = <256>; > + #address-cells = <2>; > + #size-cells = <2>; > + ranges; > + > + > + renesas,slaves = <R8A7790_DMA_SDHI0_RX CHCR_RX_256BIT>, > + <R8A7790_DMA_SDHI0_TX CHCR_TX_256BIT>; The MID/RID of slave devices are already specified in the "dmas" property of the slave devices DT nodes. Why does it need to be specified here as well ? Is the configuration hardware properties or software parameters ? In the later case shouldn't it be specified in the slave DT node instead ? > + } > + > * DMA client > > Required properties: > diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c > index 06473a0..386fd9e 100644 > --- a/drivers/dma/sh/shdma-of.c > +++ b/drivers/dma/sh/shdma-of.c > @@ -3,12 +3,15 @@ > * > * Copyright (C) 2013 Renesas Electronics Inc. > * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> > + * Copyright (c) 2014 Codethink Limited > + * Ben Dooks <ben.dooks@codethink.co.uk> > * > * This is free software; you can redistribute it and/or modify > * it under the terms of version 2 of the GNU General Public License as > * published by the Free Software Foundation. > */ > > +#include <linux/slab.h> > #include <linux/dmaengine.h> > #include <linux/module.h> > #include <linux/of.h> > @@ -16,9 +19,37 @@ > #include <linux/of_platform.h> > #include <linux/platform_device.h> > #include <linux/shdma-base.h> > +#include <linux/sh_dma.h> > + > +#include <dt-bindings/dma/shdma.h> > > #define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan) > > +#include "shdma-arm.h" > + > +static const unsigned int arm_dma_ts_shift[] = SH_DMAE_TS_SHIFT; > + > +static struct sh_dmae_pdata arm_dmae_info = { > + .ts_low_shift = SHDMA_ARM_TS_LOW_SHIFT, > + .ts_low_mask = SHDMA_ARM_TS_LOW_BIT << SHDMA_ARM_TS_LOW_SHIFT, > + .ts_high_shift = SHDMA_ARM_TS_HI_SHIFT, > + .ts_high_mask = SHDMA_ARM_TS_HI_BIT << SHDMA_ARM_TS_HI_SHIFT, > + .ts_shift = arm_dma_ts_shift, > + .ts_shift_num = ARRAY_SIZE(arm_dma_ts_shift), > + .dmaor_init = DMAOR_DME, > + .chclr_present = 1, > + .chclr_bitwise = 1, > +}; > + > +struct sh_dmae_of_info shdma_arm_info = { > + .pdata_template = &arm_dmae_info, > + .channel_offset = 0x8000-0x20, > + .channel_stride = 0x80, > + .offset = 0x0, > + .dmars = 0x40, > + .chclr_offset = 0x80, > +}; > + > static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec, > struct of_dma *ofdma) > { > @@ -40,6 +71,109 @@ static struct dma_chan *shdma_of_xlate(struct > of_phandle_args *dma_spec, return chan; > } > > +const struct sh_dmae_pdata * > +sh_dma_probe_of(struct platform_device *pdev, const struct of_device_id > *ofmatch) +{ > + const struct device_node *np = pdev->dev.of_node; > + const struct sh_dmae_of_info *ofinf; > + struct device *dev = &pdev->dev; > + struct sh_dmae_pdata *pdata; > + struct sh_dmae_channel *chan; > + struct property *prop; > + u32 nr_chan; > + unsigned ch; > + int ret; > + int len; > + > + if (!ofmatch) > + return NULL; > + > + ofinf = ofmatch->data; > + > + pdata = devm_kzalloc(dev, sizeof(struct sh_dmae_pdata), GFP_KERNEL); > + if (!pdata) { > + dev_err(dev, "failed to make platform data\n"); > + return NULL; > + } > + > + *pdata = *ofinf->pdata_template; /* copy in template first */ > + > + ret = of_property_read_u32(np, "dma-channels", &nr_chan); > + if (ret < 0) { > + dev_err(dev, "failed to get number of channels\n"); > + return NULL; > + } > + > + chan = devm_kzalloc(dev, nr_chan * sizeof(struct sh_dmae_channel), > + GFP_KERNEL); > + if (!chan) { > + dev_err(dev, "cannot allocate %d channels\n", nr_chan); > + return NULL; > + } > + > + pdata->channel = chan; > + pdata->channel_num = nr_chan; > + > + dev_dbg(dev, "%d dma channels allocated\n", nr_chan); > + > + for (ch = 0; ch < nr_chan; ch++) { > + struct sh_dmae_channel *cp = chan + ch; > + u32 base = ofinf->channel_offset + ofinf->channel_stride * ch; > + > + cp->offset = base + ofinf->offset; > + cp->dmars = base + ofinf->dmars; > + cp->chclr_bit = ch; > + cp->chclr_offset = ofinf->chclr_offset; > + > + dev_dbg(dev, "ch %d: off %08x, dmars %08x, bit %d, off %d\n", > + ch, cp->offset, cp->dmars, > + cp->chclr_bit, cp->chclr_offset); > + } > + > + /* look in current, or parent node for the slave mappings */ > + prop = of_find_property(np, "renesas,slaves", &len); > + if (!prop) > + prop = of_find_property(np->parent, "renesas,slaves", &len); > + > + if (prop) { > + struct sh_dmae_slave_config *slaves; > + int nr_slaves = len / (sizeof(u32) * 3); > + const __be32 *of_ptr; > + u32 of_idx; > + > + slaves = devm_kzalloc(dev, sizeof(*slaves) * nr_slaves, > + GFP_KERNEL); > + if (!slaves) { > + dev_err(dev, "cannot allocate %d slaves\n", nr_slaves); > + return NULL; > + } > + > + pdata->slave = slaves; > + pdata->slave_num = nr_slaves; > + of_idx = 0; > + of_ptr = NULL; > + > + dev_dbg(dev, "building %d slaves\n", nr_slaves); > + > + for (; nr_slaves > 0; nr_slaves--, slaves++) { > + of_ptr= of_prop_next_u32(prop, of_ptr, &of_idx); > + slaves->mid_rid = be32_to_cpu(*of_ptr); > + slaves->slave_id = slaves->mid_rid; > + > + of_ptr= of_prop_next_u32(prop, of_ptr, &of_idx); > + slaves->chcr = be32_to_cpu(*of_ptr); > + > + dev_dbg(dev, "slave: id %02x, chcr %08x, addr %08x\n", > + slaves->mid_rid, slaves->chcr, slaves->addr); > + } > + } else { > + dev_warn(dev, "did not find any slave information\n"); > + } > + > + pdev->dev.platform_data = pdata; > + return pdata; > +}; > + > static int shdma_of_probe(struct platform_device *pdev) > { > const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev); > diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h > index 758a57b..0db8327 100644 > --- a/drivers/dma/sh/shdma.h > +++ b/drivers/dma/sh/shdma.h > @@ -56,6 +56,26 @@ struct sh_dmae_desc { > struct shdma_desc shdma_desc; > }; > > +/* > + * Template information for building shdma data, provided as part of the > + * data field in the of_device_id structure. This is then used to build > + * the platform data for the dma code. > + */ > +struct sh_dmae_of_info { > + struct sh_dmae_pdata *pdata_template; > + unsigned int channel_offset; > + unsigned int channel_stride; > + int offset; > + int dmars; > + int chclr_offset; > + int chclr_bit; > +}; > + > +extern struct sh_dmae_of_info shdma_arm_info; > + > +extern const struct sh_dmae_pdata *sh_dma_probe_of(struct platform_device > *pdev, + const struct of_device_id *match); > + > #define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, > shdma_chan) #define to_sh_desc(lh) container_of(lh, struct sh_desc, node) > #define tx_to_sh_desc(tx) container_of(tx, struct sh_desc, async_tx) > diff --git a/include/dt-bindings/dma/shdma.h > b/include/dt-bindings/dma/shdma.h new file mode 100644 > index 0000000..0c8fc9e > --- /dev/null > +++ b/include/dt-bindings/dma/shdma.h > @@ -0,0 +1,45 @@ > +/* DMA binding definitions for SH-DMAC engines. > + * > + * Moved from sh_dma.h to share with device tree by Ben Dooks. > + * Orignal code from: > + * shdma.h: Copyright (C) 2010 Guennadi Liakhovetski > <g.liakhovetski@gmx.de> + * shdma-arm.h: Copyright (C) 2013 Renesas > Electronics, Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#define SHDMA_DM_INC 0x00004000 > +#define SHDMA_DM_DEC 0x00008000 > +#define SHDMA_DM_FIX 0x0000c000 > +#define SHDMA_SM_INC 0x00001000 > +#define SHDMA_SM_DEC 0x00002000 > +#define SHDMA_SM_FIX 0x00003000 > +#define SHDMA_CHCR_DE 0x00000001 > +#define SHDMA_CHCR_TE 0x00000002 > +#define SHDMA_CHCR_IE 0x00000004 > + > +/* ARM specific definitions */ > + > +#define SHDMA_ARM_SZ_8BIT (0) > +#define SHDMA_ARM_SZ_16BIT (1) > +#define SHDMA_ARM_SZ_32BIT (2) > +#define SHDMA_ARM_SZ_64BIT (7) > +#define SHDMA_ARM_SZ_128BIT (3) > +#define SHDMA_ARM_SZ_256BIT (4) > +#define SHDMA_ARM_SZ_512BIT (5) > + > +#define SHDMA_ARM_TS_LOW_BIT (0x3) > +#define SHDMA_ARM_TS_HI_BIT (0xc) > + > +#define SHDMA_ARM_TS_LOW_SHIFT (3) > +#define SHDMA_ARM_TS_HI_SHIFT (20 - 2) /* 2 bits for shifted low TS */ > + > +#define SHDMA_ARM_TS_INDEX2VAL(i) \ > + ((((i) & SHDMA_ARM_TS_LOW_BIT) << SHDMA_ARM_TS_LOW_SHIFT) |\ > + (((i) & SHDMA_ARM_TS_HI_BIT) << SHDMA_ARM_TS_HI_SHIFT)) > + > +#define SHDMA_ARM_CHCR_RX(size) (SHDMA_DM_INC | SHDMA_SM_FIX | 0x800 | > SHDMA_ARM_TS_INDEX2VAL(size)) +#define SHDMA_ARM_CHCR_TX(size) > (SHDMA_DM_FIX | SHDMA_SM_INC | 0x800 | SHDMA_ARM_TS_INDEX2VAL(size)) +
diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt index 2a3f3b8..7d9e7bd 100644 --- a/Documentation/devicetree/bindings/dma/shdma.txt +++ b/Documentation/devicetree/bindings/dma/shdma.txt @@ -15,6 +15,12 @@ Required properties: - compatible: should be "renesas,shdma-mux" - #dma-cells: should be <1>, see "dmas" property below +New properites, required for renesas,dma-r8a7790. +- reneasa,slaves: A list of DMA channel MID/RID and the configuration to + go with them. These pairs are in the form of: + < mid+rid configuration> + + Optional properties (currently unused): - dma-channels: number of DMA channels - dma-requests: number of DMA request signals @@ -25,6 +31,7 @@ Required properties: - compatible: should be of the form "renesas,shdma-<soc>", where <soc> should be replaced with the desired SoC model, e.g. "renesas,shdma-r8a73a4" for the system DMAC on r8a73a4 SoC + "renesas,dma-r8a7790" for the DMAC on the R8A7790. Example: dmac: dma-multiplexer@0 { @@ -70,6 +77,23 @@ Example: }; }; +For r8a7790, the following is an example of using the reneasas,slaves to +configure the slave channels on the controller: + + dma0: dma-mux@0 { + compatible = "renesas,shdma-mux"; + #dma-cells = <1>; + dma-channels = <20>; + dma-requests = <256>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + + renesas,slaves = <R8A7790_DMA_SDHI0_RX CHCR_RX_256BIT>, + <R8A7790_DMA_SDHI0_TX CHCR_TX_256BIT>; + } + * DMA client Required properties: diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c index 06473a0..386fd9e 100644 --- a/drivers/dma/sh/shdma-of.c +++ b/drivers/dma/sh/shdma-of.c @@ -3,12 +3,15 @@ * * Copyright (C) 2013 Renesas Electronics Inc. * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * Copyright (c) 2014 Codethink Limited + * Ben Dooks <ben.dooks@codethink.co.uk> * * This is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. */ +#include <linux/slab.h> #include <linux/dmaengine.h> #include <linux/module.h> #include <linux/of.h> @@ -16,9 +19,37 @@ #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/shdma-base.h> +#include <linux/sh_dma.h> + +#include <dt-bindings/dma/shdma.h> #define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan) +#include "shdma-arm.h" + +static const unsigned int arm_dma_ts_shift[] = SH_DMAE_TS_SHIFT; + +static struct sh_dmae_pdata arm_dmae_info = { + .ts_low_shift = SHDMA_ARM_TS_LOW_SHIFT, + .ts_low_mask = SHDMA_ARM_TS_LOW_BIT << SHDMA_ARM_TS_LOW_SHIFT, + .ts_high_shift = SHDMA_ARM_TS_HI_SHIFT, + .ts_high_mask = SHDMA_ARM_TS_HI_BIT << SHDMA_ARM_TS_HI_SHIFT, + .ts_shift = arm_dma_ts_shift, + .ts_shift_num = ARRAY_SIZE(arm_dma_ts_shift), + .dmaor_init = DMAOR_DME, + .chclr_present = 1, + .chclr_bitwise = 1, +}; + +struct sh_dmae_of_info shdma_arm_info = { + .pdata_template = &arm_dmae_info, + .channel_offset = 0x8000-0x20, + .channel_stride = 0x80, + .offset = 0x0, + .dmars = 0x40, + .chclr_offset = 0x80, +}; + static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { @@ -40,6 +71,109 @@ static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec, return chan; } +const struct sh_dmae_pdata * +sh_dma_probe_of(struct platform_device *pdev, const struct of_device_id *ofmatch) +{ + const struct device_node *np = pdev->dev.of_node; + const struct sh_dmae_of_info *ofinf; + struct device *dev = &pdev->dev; + struct sh_dmae_pdata *pdata; + struct sh_dmae_channel *chan; + struct property *prop; + u32 nr_chan; + unsigned ch; + int ret; + int len; + + if (!ofmatch) + return NULL; + + ofinf = ofmatch->data; + + pdata = devm_kzalloc(dev, sizeof(struct sh_dmae_pdata), GFP_KERNEL); + if (!pdata) { + dev_err(dev, "failed to make platform data\n"); + return NULL; + } + + *pdata = *ofinf->pdata_template; /* copy in template first */ + + ret = of_property_read_u32(np, "dma-channels", &nr_chan); + if (ret < 0) { + dev_err(dev, "failed to get number of channels\n"); + return NULL; + } + + chan = devm_kzalloc(dev, nr_chan * sizeof(struct sh_dmae_channel), + GFP_KERNEL); + if (!chan) { + dev_err(dev, "cannot allocate %d channels\n", nr_chan); + return NULL; + } + + pdata->channel = chan; + pdata->channel_num = nr_chan; + + dev_dbg(dev, "%d dma channels allocated\n", nr_chan); + + for (ch = 0; ch < nr_chan; ch++) { + struct sh_dmae_channel *cp = chan + ch; + u32 base = ofinf->channel_offset + ofinf->channel_stride * ch; + + cp->offset = base + ofinf->offset; + cp->dmars = base + ofinf->dmars; + cp->chclr_bit = ch; + cp->chclr_offset = ofinf->chclr_offset; + + dev_dbg(dev, "ch %d: off %08x, dmars %08x, bit %d, off %d\n", + ch, cp->offset, cp->dmars, + cp->chclr_bit, cp->chclr_offset); + } + + /* look in current, or parent node for the slave mappings */ + prop = of_find_property(np, "renesas,slaves", &len); + if (!prop) + prop = of_find_property(np->parent, "renesas,slaves", &len); + + if (prop) { + struct sh_dmae_slave_config *slaves; + int nr_slaves = len / (sizeof(u32) * 3); + const __be32 *of_ptr; + u32 of_idx; + + slaves = devm_kzalloc(dev, sizeof(*slaves) * nr_slaves, + GFP_KERNEL); + if (!slaves) { + dev_err(dev, "cannot allocate %d slaves\n", nr_slaves); + return NULL; + } + + pdata->slave = slaves; + pdata->slave_num = nr_slaves; + of_idx = 0; + of_ptr = NULL; + + dev_dbg(dev, "building %d slaves\n", nr_slaves); + + for (; nr_slaves > 0; nr_slaves--, slaves++) { + of_ptr= of_prop_next_u32(prop, of_ptr, &of_idx); + slaves->mid_rid = be32_to_cpu(*of_ptr); + slaves->slave_id = slaves->mid_rid; + + of_ptr= of_prop_next_u32(prop, of_ptr, &of_idx); + slaves->chcr = be32_to_cpu(*of_ptr); + + dev_dbg(dev, "slave: id %02x, chcr %08x, addr %08x\n", + slaves->mid_rid, slaves->chcr, slaves->addr); + } + } else { + dev_warn(dev, "did not find any slave information\n"); + } + + pdev->dev.platform_data = pdata; + return pdata; +}; + static int shdma_of_probe(struct platform_device *pdev) { const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev); diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h index 758a57b..0db8327 100644 --- a/drivers/dma/sh/shdma.h +++ b/drivers/dma/sh/shdma.h @@ -56,6 +56,26 @@ struct sh_dmae_desc { struct shdma_desc shdma_desc; }; +/* + * Template information for building shdma data, provided as part of the + * data field in the of_device_id structure. This is then used to build + * the platform data for the dma code. + */ +struct sh_dmae_of_info { + struct sh_dmae_pdata *pdata_template; + unsigned int channel_offset; + unsigned int channel_stride; + int offset; + int dmars; + int chclr_offset; + int chclr_bit; +}; + +extern struct sh_dmae_of_info shdma_arm_info; + +extern const struct sh_dmae_pdata *sh_dma_probe_of(struct platform_device *pdev, + const struct of_device_id *match); + #define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, shdma_chan) #define to_sh_desc(lh) container_of(lh, struct sh_desc, node) #define tx_to_sh_desc(tx) container_of(tx, struct sh_desc, async_tx) diff --git a/include/dt-bindings/dma/shdma.h b/include/dt-bindings/dma/shdma.h new file mode 100644 index 0000000..0c8fc9e --- /dev/null +++ b/include/dt-bindings/dma/shdma.h @@ -0,0 +1,45 @@ +/* DMA binding definitions for SH-DMAC engines. + * + * Moved from sh_dma.h to share with device tree by Ben Dooks. + * Orignal code from: + * shdma.h: Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * shdma-arm.h: Copyright (C) 2013 Renesas Electronics, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define SHDMA_DM_INC 0x00004000 +#define SHDMA_DM_DEC 0x00008000 +#define SHDMA_DM_FIX 0x0000c000 +#define SHDMA_SM_INC 0x00001000 +#define SHDMA_SM_DEC 0x00002000 +#define SHDMA_SM_FIX 0x00003000 +#define SHDMA_CHCR_DE 0x00000001 +#define SHDMA_CHCR_TE 0x00000002 +#define SHDMA_CHCR_IE 0x00000004 + +/* ARM specific definitions */ + +#define SHDMA_ARM_SZ_8BIT (0) +#define SHDMA_ARM_SZ_16BIT (1) +#define SHDMA_ARM_SZ_32BIT (2) +#define SHDMA_ARM_SZ_64BIT (7) +#define SHDMA_ARM_SZ_128BIT (3) +#define SHDMA_ARM_SZ_256BIT (4) +#define SHDMA_ARM_SZ_512BIT (5) + +#define SHDMA_ARM_TS_LOW_BIT (0x3) +#define SHDMA_ARM_TS_HI_BIT (0xc) + +#define SHDMA_ARM_TS_LOW_SHIFT (3) +#define SHDMA_ARM_TS_HI_SHIFT (20 - 2) /* 2 bits for shifted low TS */ + +#define SHDMA_ARM_TS_INDEX2VAL(i) \ + ((((i) & SHDMA_ARM_TS_LOW_BIT) << SHDMA_ARM_TS_LOW_SHIFT) |\ + (((i) & SHDMA_ARM_TS_HI_BIT) << SHDMA_ARM_TS_HI_SHIFT)) + +#define SHDMA_ARM_CHCR_RX(size) (SHDMA_DM_INC | SHDMA_SM_FIX | 0x800 | SHDMA_ARM_TS_INDEX2VAL(size)) +#define SHDMA_ARM_CHCR_TX(size) (SHDMA_DM_FIX | SHDMA_SM_INC | 0x800 | SHDMA_ARM_TS_INDEX2VAL(size)) +
Add support for building shdma internal data from the device tree to allow converting the driver to be device tree enabled. It includes a helper for the of case to build the internal data used to select and filter out the DMA channels from the ID information in the device tree. Also updates the documentation for the DT case. Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> --- Documentation/devicetree/bindings/dma/shdma.txt | 24 +++++ drivers/dma/sh/shdma-of.c | 134 ++++++++++++++++++++++++ drivers/dma/sh/shdma.h | 20 ++++ include/dt-bindings/dma/shdma.h | 45 ++++++++ 4 files changed, 223 insertions(+) create mode 100644 include/dt-bindings/dma/shdma.h