From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [v9,1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support From: Long Cheng Message-Id: <1547108685.3831.21.camel@mhfsdcap03> Date: Thu, 10 Jan 2019 16:24:45 +0800 To: Nicolas Boichat Cc: Vinod Koul , Randy Dunlap , Rob Herring , Mark Rutland , Ryder Lee , Sean Wang , Matthias Brugger , Dan Williams , Greg Kroah-Hartman , Jiri Slaby , Sean Wang , dmaengine@vger.kernel.org, devicetree@vger.kernel.org, linux-arm Mailing List , linux-mediatek@lists.infradead.org, lkml , linux-serial@vger.kernel.org, srv_heupstream@mediatek.com, Yingjoe Chen , YT Shen , Zhenbao Liu , Long Cheng List-ID: T24gVGh1LCAyMDE5LTAxLTAzIGF0IDA5OjM5ICswODAwLCBOaWNvbGFzIEJvaWNoYXQgd3JvdGU6 Cj4gT24gV2VkLCBKYW4gMiwgMjAxOSBhdCAxMDoxMyBBTSBMb25nIENoZW5nIDxsb25nLmNoZW5n QG1lZGlhdGVrLmNvbT4gd3JvdGU6Cj4gPgoKLi4uLi4KCj4gPiArLyogaW50ZXJydXB0IHRyaWdn ZXIgbGV2ZWwgZm9yIHR4ICovCj4gPiArI2RlZmluZSBWRkZfVFhfVEhSRShuKSAgICAgICAgICgo bikgKiA3IC8gOCkKPiA+ICsvKiBpbnRlcnJ1cHQgdHJpZ2dlciBsZXZlbCBmb3IgcnggKi8KPiA+ ICsjZGVmaW5lIFZGRl9SWF9USFJFKG4pICAgICAgICAgKChuKSAqIDMgLyA0KQo+ID4gKwo+ID4g KyNkZWZpbmUgVkZGX1JJTkdfU0laRSAgMHhmZmZmVQo+IAo+IFdlbGwsIHRoZSBzaXplIGlzIGFj dHVhbGx5IDB4MTAwMDAuIE1heWJlIGNhbGwgdGhpcyBWRkZfUklOR19TSVpFX01BU0s/Cj4gCgp0 aGUgbWF4IGxlbmd0aCBpcyAweGZmZmYuICB0aGUgYml0IDE2IGlzIHdyYXAgYml0LiBvdXIgYnVm ZmVyIGlzIHJpbmcKYnVmZmVyLiBTbyBub3QgbWFzay4KCj4gPiArLyogaW52ZXJ0IHRoaXMgYml0 IHdoZW4gd3JhcCByaW5nIGhlYWQgYWdhaW4qLwo+ID4gKyNkZWZpbmUgVkZGX1JJTkdfV1JBUCAg MHgxMDAwMFUKPiA+ICsKPiA+ICsgICAgICAgd3JpdGVsKHZhbCwgYy0+YmFzZSArIHJlZyk7Cj4g PiArfQo+ID4gKwoKLi4uLi4uCgo+ID4gK3N0YXRpYyB2b2lkIG10a191YXJ0X2FwZG1hX3N0YXJ0 X3R4KHN0cnVjdCBtdGtfY2hhbiAqYykKPiA+ICt7Cj4gPiArICAgICAgIHVuc2lnbmVkIGludCBs ZW4sIHNlbmQsIGxlZnQsIHdwdCwgZF93cHQsIHRtcDsKPiA+ICsgICAgICAgaW50IHJldDsKPiA+ ICsKPiA+ICsgICAgICAgbGVmdCA9IG10a191YXJ0X2FwZG1hX3JlYWQoYywgVkZGX0xFRlRfU0la RSk7Cj4gPiArICAgICAgIGlmICghbGVmdCkgewo+ID4gKyAgICAgICAgICAgICAgIG10a191YXJ0 X2FwZG1hX3dyaXRlKGMsIFZGRl9JTlRfRU4sIFZGRl9UWF9JTlRfRU5fQik7Cj4gPiArICAgICAg ICAgICAgICAgcmV0dXJuOwo+ID4gKyAgICAgICB9Cj4gPiArCj4gPiArICAgICAgIC8qIFdhaXQg MXNlYyBmb3IgZmx1c2gsICBjYW4ndCBzbGVlcCovCj4gCj4gbml0OiBvbmUgc3BhY2UgYWZ0ZXIg JywnLCBwZXJpb2QgYWZ0ZXIgJ3NsZWVwJywgc3BhY2UgYmVmb3JlICcqJy4KPiAKPiA+ICsgICAg ICAgcmV0ID0gcmVhZHhfcG9sbF90aW1lb3V0KHJlYWRsLCBjLT5iYXNlICsgVkZGX0ZMVVNILCB0 bXAsCj4gPiArICAgICAgICAgICAgICAgICAgICAgICB0bXAgIT0gVkZGX0ZMVVNIX0IsIDAsIDEw MDAwMDApOwo+ID4gKyAgICAgICBpZiAocmV0KQo+ID4gKyAgICAgICAgICAgICAgIGRldl93YXJu KGMtPnZjLmNoYW4uZGV2aWNlLT5kZXYsICJ0eDogZmFpbCwgZGVidWc9MHgleFxuIiwKPiA+ICsg ICAgICAgICAgICAgICAgICAgICAgIG10a191YXJ0X2FwZG1hX3JlYWQoYywgVkZGX0RFQlVHX1NU QVRVUykpOwo+IAo+IFdoeSBkbyB3ZSBuZWVkIHRvIHdhaXQgZm9yIGZsdXNoIG5vdz8gVGhlIHBy ZXZpb3VzIGltcGxlbWVudGF0aW9uIGRpZAo+IG5vdCByZXF1aXJlIHRoaXMuLi4KPiAKCmJlY2F1 c2Ugb3VyIEhXIGJ1ZmZlciBpcyBjeWNsaWMuIGF0IG9uZSB0eCwgaWYgdGhlIHNpemUgb2YgZGF0 YSBpcwpiaWdnZXIsIGRhdGEgbWF5YmUgY292ZXIuIFNvIG11c3Qgd2FpdCBmbHVzaCBmaW5pc2gu IGNvbmZpcm0gdGhlIGRhdGEgaXMKcmlnaHQuIGxpa2UgMTI4IGJ5dGVzIHNpemUsIHNtYWxsIGxl bmd0aCBjYW4ndCByZXByb2R1Y2UgdGhlIGlzc3VlLgoKPiA+ICsKPiA+ICsgICAgICAgc2VuZCA9 IG1pbl90KHVuc2lnbmVkIGludCwgbGVmdCwgYy0+ZGVzYy0+YXZhaWxfbGVuKTsKPiA+ICsgICAg ICAgd3B0ID0gbXRrX3VhcnRfYXBkbWFfcmVhZChjLCBWRkZfV1BUKTsKPiA+ICsgICAgICAgbGVu ID0gbXRrX3VhcnRfYXBkbWFfcmVhZChjLCBWRkZfTEVOKTsKPiA+ICsKPiA+ICsgICAgICAgZF93 cHQgPSB3cHQgKyBzZW5kOwo+ID4gKyAgICAgICBpZiAoKGRfd3B0ICYgVkZGX1JJTkdfU0laRSkg Pj0gbGVuKSB7Cj4gCj4gSSBkb24ndCBnZXQgd2h5IHlvdSBuZWVkIHRvIGFkZCAiJiBWRkZfUklO R19TSVpFIi4gSWYgd3B0ICsgc2VuZCA+Cj4gVkZGX1JJTkdfU0laRSwgZG9uJ3QgeW91IG5lZWQg dG8gdG9nZ2xlIFZGRl9SSU5HX1dSQVAgdG9vPwoKdGhlIGxvbmdlc3QgYWN0dWFsIGxlbmd0aCBp cyBWRkZfUklOR19TSVpFLiBvbmUgY3ljbGljLCB3aWxsIHNldCBiaXRbMTZdCnRvIH5iaXRbMTZd LiB0aGUgYml0WzAgfiAxNV0gaXMgYWN0dWFsIGFkZHJlc3MuIFNvIG5lZWQgZ2V0IHJpZCBvZgpi aXRbMTZdCgo+IAo+ID4gKyAgICAgICAgICAgICAgIGRfd3B0ID0gZF93cHQgLSBsZW47Cj4gPiAr ICAgICAgICAgICAgICAgZF93cHQgPSBkX3dwdCBeIFZGRl9SSU5HX1dSQVA7Cj4gPiArICAgICAg IH0KPiA+ICsgICAgICAgbXRrX3VhcnRfYXBkbWFfd3JpdGUoYywgVkZGX1dQVCwgZF93cHQpOwo+ ID4gKwo+ID4gKyAgICAgICBjLT5kZXNjLT5hdmFpbF9sZW4gLT0gc2VuZDsKPiA+ICsKPiA+ICsg ICAgICAgbXRrX3VhcnRfYXBkbWFfd3JpdGUoYywgVkZGX0lOVF9FTiwgVkZGX1RYX0lOVF9FTl9C KTsKPiA+ICsgICAgICAgaWYgKG10a191YXJ0X2FwZG1hX3JlYWQoYywgVkZGX0ZMVVNIKSA9PSAw VSkKPiA+ICsgICAgICAgICAgICAgICBtdGtfdWFydF9hcGRtYV93cml0ZShjLCBWRkZfRkxVU0gs IFZGRl9GTFVTSF9CKTsKPiA+ICt9Cj4gCj4gKHRoYW5rcyBmb3IgdGhlIHJlc3Qgb2YgdGhlIGNo YW5nZXMsIHRoaXMgbG9va3MgbXVjaCBtb3JlIHJlYWRhYmxlKQo+IAo+ID4gKwouLi4uLi4KCj4g PiArCj4gPiArc3RhdGljIGludCBtdGtfdWFydF9hcGRtYV9kZXZpY2VfcGF1c2Uoc3RydWN0IGRt YV9jaGFuICpjaGFuKQo+ID4gK3sKPiA+ICsgICAgICAgLyoganVzdCBmb3IgY2hlY2sgY2FwcyBw YXNzICovCj4gPiArICAgICAgIHJldHVybiAwOwo+ID4gK30KPiAKPiBUaGlzIGlzIHN0aWxsIG5v dCByaWdodC4uLiBIb3BlZnVsbHkgc29tZWJvZHkgbW9yZSBmYW1pbGlhciB3aXRoIHRoZQo+IERN QSBzdWJzeXN0ZW0gY2FuIHdlaWdoIGluLCBidXQgbWF5YmUgaXQncyBlbm91Z2ggdG8gd2FpdCBm b3IgdGhlCj4gY3VycmVudCB0cmFuc2ZlciB0byBiZSBmbHVzaGVkIGFuZCB0ZW1wb3JhcmlseSBk aXNhYmxlIGludGVycnVwdHM/Cj4gZS5nLiBjYWxsIG10a191YXJ0X2FwZG1hX3Rlcm1pbmF0ZV9h bGwgYWJvdmU/Cj4gCgppIGhhZCByZXZpZXcgdGhlIDgyNTAgVUFSVCBmcmFtZXdvcmsuIGp1c3Qg Y2hlY2sgdGhlIGZ1bmN0aW9uIHBvaW50ZXIsCm5vdCB1c2UuIGFuZCBvdXIgSFcgY2FuJ3Qgc3Vw cG9ydCB0aGUgZmVhdHVyZS4gU28gaSBqdXN0IGtlZXAgaXQgYXQKZmlyc3QgdmVyc2lvbi4KCj4g PiArCj4gPiArc3RhdGljIGludCBtdGtfdWFydF9hcGRtYV9kZXZpY2VfcmVzdW1lKHN0cnVjdCBk bWFfY2hhbiAqY2hhbikKPiA+ICt7Cj4gPiArICAgICAgIC8qIGp1c3QgZm9yIGNoZWNrIGNhcHMg cGFzcyAqLwo+ID4gKyAgICAgICByZXR1cm4gMDsKPiA+ICt9Cj4gCj4gRHJvcCB0aGlzIG9uZSBz aW5jZSB5b3UgZG9uJ3QgcmVhbGx5IG5lZWQgaXQuCj4gCgpvaywgaSB3aWxsIHJlbW92ZSBpdC4K Cj4gPiArCj4gPiArc3RhdGljIHZvaWQgbXRrX3VhcnRfYXBkbWFfZnJlZShzdHJ1Y3QgbXRrX3Vh cnRfYXBkbWFkZXYgKm10a2QpCj4gPiArewo+ID4gKyAgICAgICB3aGlsZSAobGlzdF9lbXB0eSgm bXRrZC0+ZGRldi5jaGFubmVscykgPT0gMCkgewo+IAo+ICFsaXN0X2VtcHR5KAo+IAo+ID4gKyAg ICAgICAgICAgICAgIHN0cnVjdCBtdGtfY2hhbiAqYyA9IGxpc3RfZmlyc3RfZW50cnkoJm10a2Qt PmRkZXYuY2hhbm5lbHMsCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgbXRrX2No YW4sIHZjLmNoYW4uZGV2aWNlX25vZGUpOwo+ID4gKwo+ID4gKyAgICAgICAgICAgICAgIGxpc3Rf ZGVsKCZjLT52Yy5jaGFuLmRldmljZV9ub2RlKTsKPiA+ICsgICAgICAgICAgICAgICB0YXNrbGV0 X2tpbGwoJmMtPnZjLnRhc2spOwo+ID4gKyAgICAgICB9Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRp YyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIG10a191YXJ0X2FwZG1hX21hdGNoW10gPSB7Cj4g PiArICAgICAgIHsgLmNvbXBhdGlibGUgPSAibWVkaWF0ZWssbXQ2NTc3LXVhcnQtZG1hIiwgfSwK PiA+ICsgICAgICAgeyAvKiBzZW50aW5lbCAqLyB9LAo+ID4gK307Cj4gPiArTU9EVUxFX0RFVklD RV9UQUJMRShvZiwgbXRrX3VhcnRfYXBkbWFfbWF0Y2gpOwo+ID4gKwo+ID4gK3N0YXRpYyBpbnQg bXRrX3VhcnRfYXBkbWFfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiA+ICt7 Cj4gPiArICAgICAgIHN0cnVjdCBtdGtfdWFydF9hcGRtYWRldiAqbXRrZDsKPiA+ICsgICAgICAg c3RydWN0IHJlc291cmNlICpyZXM7Cj4gPiArICAgICAgIHN0cnVjdCBtdGtfY2hhbiAqYzsKPiA+ ICsgICAgICAgdW5zaWduZWQgaW50IGk7Cj4gPiArICAgICAgIGludCByYzsKPiA+ICsKPiA+ICsg ICAgICAgbXRrZCA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplb2YoKm10a2QpLCBHRlBf S0VSTkVMKTsKPiA+ICsgICAgICAgaWYgKCFtdGtkKQo+ID4gKyAgICAgICAgICAgICAgIHJldHVy biAtRU5PTUVNOwo+ID4gKwo+ID4gKyAgICAgICBtdGtkLT5jbGsgPSBkZXZtX2Nsa19nZXQoJnBk ZXYtPmRldiwgTlVMTCk7Cj4gPiArICAgICAgIGlmIChJU19FUlIobXRrZC0+Y2xrKSkgewo+ID4g KyAgICAgICAgICAgICAgIGRldl9lcnIoJnBkZXYtPmRldiwgIk5vIGNsb2NrIHNwZWNpZmllZFxu Iik7Cj4gPiArICAgICAgICAgICAgICAgcmMgPSBQVFJfRVJSKG10a2QtPmNsayk7Cj4gPiArICAg ICAgICAgICAgICAgcmV0dXJuIHJjOwo+ID4gKyAgICAgICB9Cj4gPiArCj4gPiArICAgICAgIGlm IChvZl9wcm9wZXJ0eV9yZWFkX2Jvb2wocGRldi0+ZGV2Lm9mX25vZGUsICJkbWEtMzNiaXRzIikp Cj4gPiArICAgICAgICAgICAgICAgbXRrZC0+c3VwcG9ydF8zM2JpdHMgPSB0cnVlOwo+IAo+IEkg ZG9uJ3QgdGhpbmsgdGhpcyBzaG91bGQgYmUgYSBkZXZpY2UgdHJlZSBwcm9wZXJ0eS4gVHlwaWNh bGx5IHdlJ2QKPiBoYXZlIG11bHRpcGxlIGNvbXBhdGlibGUgc3RyaW5ncyBmb3IgKHNsaWdodGx5 KSBkaWZmZXJlbnQgSFcgYmxvY2tzLAo+IGFuZCBlbmFibGUgMzNiaXRzIG9ubHkgb24gSFcgdGhh dCBoYXZlIHN1cHBvcnQuCj4gCj4gU2VlIGhvdyBpdCdzIGRvbmUgaW4gZHJpdmVycy9pMmMvYnVz c2VzL2kyYy1tdDY1eHguYywgZm9yIGV4YW1wbGUuCj4gCgppbiBNZWRpYVRlaywgbm90IGFsbCBJ QyBjYW4gc3VwcG9ydCAzM2JpdC4gU28gaSB3YW50IHRvIGNvbmZpZ3VyZSBieSBEVC4KU28gZG9u J3QgbmVlZCB0byBtb2RpZnkgY29kZSBpbiBOZXcgSUMuCgo+ID4gKwo+ID4gKyAgICAgICByYyA9 IGRtYV9zZXRfbWFza19hbmRfY29oZXJlbnQoJnBkZXYtPmRldiwKPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgRE1BX0JJVF9NQVNLKDMyIHwgbXRrZC0+c3VwcG9ydF8zM2JpdHMp KTsKPiAKPiBJJ2QgZmVlbCBhIGxpdHRsZSBtb3JlIGNvbmZvcnRhYmxlIGlmIHlvdSB1c2VkIGEg dmFyaWFibGUgaW5zdGVhZDoKPiAKPiBpbnQgZG1hX2JpdHMgPSAzMjsKPiAKPiBpZiAoc3VwcG9y dF8zM2JpdHMpCj4gICAgZG1hX2JpdHMgPSAzMzsKPiAKPiAuLi4sIERNQV9CSVRfTUFTSyhkbWFf Yml0cykpOwo+IAoKT0ssIGkgY2FuIG1vZGlmeSBpdC4gdGhhbmtzLgoKPiA+ICsgICAgICAgaWYg KHJjKQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybiByYzsKPiA+ICsKPiA+ICsgICAgICAgZG1h X2NhcF9zZXQoRE1BX1NMQVZFLCBtdGtkLT5kZGV2LmNhcF9tYXNrKTsKPiA+ICsgICAgICAgbXRr ZC0+ZGRldi5kZXZpY2VfYWxsb2NfY2hhbl9yZXNvdXJjZXMgPQo+ID4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBtdGtfdWFydF9hcGRtYV9hbGxvY19jaGFuX3Jlc291cmNlczsKPiA+ ICsgICAgICAgbXRrZC0+ZGRldi5kZXZpY2VfZnJlZV9jaGFuX3Jlc291cmNlcyA9Cj4gPiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG10a191YXJ0X2FwZG1hX2ZyZWVfY2hhbl9yZXNv dXJjZXM7Cj4gPiArICAgICAgIG10a2QtPmRkZXYuZGV2aWNlX3R4X3N0YXR1cyA9IG10a191YXJ0 X2FwZG1hX3R4X3N0YXR1czsKPiA+ICsgICAgICAgbXRrZC0+ZGRldi5kZXZpY2VfaXNzdWVfcGVu ZGluZyA9IG10a191YXJ0X2FwZG1hX2lzc3VlX3BlbmRpbmc7Cj4gPiArICAgICAgIG10a2QtPmRk ZXYuZGV2aWNlX3ByZXBfc2xhdmVfc2cgPSBtdGtfdWFydF9hcGRtYV9wcmVwX3NsYXZlX3NnOwo+ ID4gKyAgICAgICBtdGtkLT5kZGV2LmRldmljZV9jb25maWcgPSBtdGtfdWFydF9hcGRtYV9zbGF2 ZV9jb25maWc7Cj4gPiArICAgICAgIG10a2QtPmRkZXYuZGV2aWNlX3BhdXNlID0gbXRrX3VhcnRf YXBkbWFfZGV2aWNlX3BhdXNlOwo+ID4gKyAgICAgICBtdGtkLT5kZGV2LmRldmljZV9yZXN1bWUg PSBtdGtfdWFydF9hcGRtYV9kZXZpY2VfcmVzdW1lOwo+ID4gKyAgICAgICBtdGtkLT5kZGV2LmRl dmljZV90ZXJtaW5hdGVfYWxsID0gbXRrX3VhcnRfYXBkbWFfdGVybWluYXRlX2FsbDsKPiA+ICsg ICAgICAgbXRrZC0+ZGRldi5zcmNfYWRkcl93aWR0aHMgPSBCSVQoRE1BX1NMQVZFX0JVU1dJRFRI XzFfQllURSk7Cj4gPiArICAgICAgIG10a2QtPmRkZXYuZHN0X2FkZHJfd2lkdGhzID0gQklUKERN QV9TTEFWRV9CVVNXSURUSF8xX0JZVEUpOwo+ID4gKyAgICAgICBtdGtkLT5kZGV2LmRpcmVjdGlv bnMgPSBCSVQoRE1BX0RFVl9UT19NRU0pIHwgQklUKERNQV9NRU1fVE9fREVWKTsKPiA+ICsgICAg ICAgbXRrZC0+ZGRldi5yZXNpZHVlX2dyYW51bGFyaXR5ID0gRE1BX1JFU0lEVUVfR1JBTlVMQVJJ VFlfU0VHTUVOVDsKPiA+ICsgICAgICAgbXRrZC0+ZGRldi5kZXYgPSAmcGRldi0+ZGV2Owo+ID4g KyAgICAgICBJTklUX0xJU1RfSEVBRCgmbXRrZC0+ZGRldi5jaGFubmVscyk7Cj4gPiArCj4gPiAr ICAgICAgIGZvciAoaSA9IDA7IGkgPCBNVEtfVUFSVF9BUERNQV9DSEFOTkVMUzsgaSsrKSB7Cj4g PiArICAgICAgICAgICAgICAgYyA9IGRldm1fa3phbGxvYyhtdGtkLT5kZGV2LmRldiwgc2l6ZW9m KCpjKSwgR0ZQX0tFUk5FTCk7Cj4gPiArICAgICAgICAgICAgICAgaWYgKCFjKSB7Cj4gPiArICAg ICAgICAgICAgICAgICAgICAgICByYyA9IC1FTk9ERVY7Cj4gPiArICAgICAgICAgICAgICAgICAg ICAgICBnb3RvIGVycl9ub19kbWE7Cj4gPiArICAgICAgICAgICAgICAgfQo+ID4gKwo+ID4gKyAg ICAgICAgICAgICAgIHJlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNF X01FTSwgaSk7Cj4gPiArICAgICAgICAgICAgICAgaWYgKCFyZXMpIHsKPiA+ICsgICAgICAgICAg ICAgICAgICAgICAgIHJjID0gLUVOT0RFVjsKPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGdv dG8gZXJyX25vX2RtYTsKPiA+ICsgICAgICAgICAgICAgICB9Cj4gPiArCj4gPiArICAgICAgICAg ICAgICAgYy0+YmFzZSA9IGRldm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ZGV2LCByZXMpOwo+ ID4gKyAgICAgICAgICAgICAgIGlmIChJU19FUlIoYy0+YmFzZSkpIHsKPiA+ICsgICAgICAgICAg ICAgICAgICAgICAgIHJjID0gUFRSX0VSUihjLT5iYXNlKTsKPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgIGdvdG8gZXJyX25vX2RtYTsKPiA+ICsgICAgICAgICAgICAgICB9Cj4gPiArICAgICAg ICAgICAgICAgYy0+cmVxdWVzdGVkID0gZmFsc2U7Cj4gPiArICAgICAgICAgICAgICAgYy0+dmMu ZGVzY19mcmVlID0gbXRrX3VhcnRfYXBkbWFfZGVzY19mcmVlOwo+ID4gKyAgICAgICAgICAgICAg IHZjaGFuX2luaXQoJmMtPnZjLCAmbXRrZC0+ZGRldik7Cj4gPiArCj4gPiArICAgICAgICAgICAg ICAgbXRrZC0+ZG1hX2lycVtpXSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgaSk7Cj4gPiArICAg ICAgICAgICAgICAgaWYgKChpbnQpbXRrZC0+ZG1hX2lycVtpXSA8IDApIHsKPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgIGRldl9lcnIoJnBkZXYtPmRldiwgImZhaWxlZCB0byBnZXQgSVJRWyVk XVxuIiwgaSk7Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICByYyA9IC1FSU5WQUw7Cj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycl9ub19kbWE7Cj4gPiArICAgICAgICAgICAg ICAgfQo+ID4gKyAgICAgICB9Cj4gPiArCj4gPiArICAgICAgIHBtX3J1bnRpbWVfZW5hYmxlKCZw ZGV2LT5kZXYpOwo+ID4gKyAgICAgICBwbV9ydW50aW1lX3NldF9hY3RpdmUoJnBkZXYtPmRldik7 Cj4gPiArCj4gPiArICAgICAgIHJjID0gZG1hX2FzeW5jX2RldmljZV9yZWdpc3RlcigmbXRrZC0+ ZGRldik7Cj4gPiArICAgICAgIGlmIChyYykKPiA+ICsgICAgICAgICAgICAgICBnb3RvIHJwbV9k aXNhYmxlOwo+ID4gKwo+ID4gKyAgICAgICBwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBtdGtk KTsKPiA+ICsKPiA+ICsgICAgICAgaWYgKHBkZXYtPmRldi5vZl9ub2RlKSB7Cj4gPiArICAgICAg ICAgICAgICAgLyogRGV2aWNlLXRyZWUgRE1BIGNvbnRyb2xsZXIgcmVnaXN0cmF0aW9uICovCj4g PiArICAgICAgICAgICAgICAgcmMgPSBvZl9kbWFfY29udHJvbGxlcl9yZWdpc3RlcihwZGV2LT5k ZXYub2Zfbm9kZSwKPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIG9mX2RtYV94bGF0ZV9ieV9jaGFuX2lkLAo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgbXRrZCk7Cj4gPiArICAgICAgICAgICAgICAgaWYg KHJjKQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgZ290byBkbWFfcmVtb3ZlOwo+ID4gKyAg ICAgICB9Cj4gPiArCj4gPiArICAgICAgIHJldHVybiByYzsKPiA+ICsKPiA+ICtkbWFfcmVtb3Zl Ogo+ID4gKyAgICAgICBkbWFfYXN5bmNfZGV2aWNlX3VucmVnaXN0ZXIoJm10a2QtPmRkZXYpOwo+ ID4gK3JwbV9kaXNhYmxlOgo+ID4gKyAgICAgICBwbV9ydW50aW1lX2Rpc2FibGUoJnBkZXYtPmRl dik7Cj4gPiArZXJyX25vX2RtYToKPiA+ICsgICAgICAgbXRrX3VhcnRfYXBkbWFfZnJlZShtdGtk KTsKPiA+ICsgICAgICAgcmV0dXJuIHJjOwo+ID4gK30KPiA+ICsKCi4uLi4uLgo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: Long Cheng Subject: Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support Date: Thu, 10 Jan 2019 16:24:45 +0800 Message-ID: <1547108685.3831.21.camel@mhfsdcap03> References: <1546395178-8880-1-git-send-email-long.cheng@mediatek.com> <1546395178-8880-2-git-send-email-long.cheng@mediatek.com> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: Sender: linux-kernel-owner@vger.kernel.org To: Nicolas Boichat Cc: Vinod Koul , Randy Dunlap , Rob Herring , Mark Rutland , Ryder Lee , Sean Wang , Matthias Brugger , Dan Williams , Greg Kroah-Hartman , Jiri Slaby , Sean Wang , dmaengine@vger.kernel.org, devicetree@vger.kernel.org, linux-arm Mailing List , linux-mediatek@lists.infradead.org, lkml , linux-serial@vger.kernel.org, srv_heupstream@mediatek.com, Yingjoe Chen , YT Shen , Z List-Id: linux-mediatek@lists.infradead.org On Thu, 2019-01-03 at 09:39 +0800, Nicolas Boichat wrote: > On Wed, Jan 2, 2019 at 10:13 AM Long Cheng wrote: > > ..... > > +/* interrupt trigger level for tx */ > > +#define VFF_TX_THRE(n) ((n) * 7 / 8) > > +/* interrupt trigger level for rx */ > > +#define VFF_RX_THRE(n) ((n) * 3 / 4) > > + > > +#define VFF_RING_SIZE 0xffffU > > Well, the size is actually 0x10000. Maybe call this VFF_RING_SIZE_MASK? > the max length is 0xffff. the bit 16 is wrap bit. our buffer is ring buffer. So not mask. > > +/* invert this bit when wrap ring head again*/ > > +#define VFF_RING_WRAP 0x10000U > > + > > + writel(val, c->base + reg); > > +} > > + ...... > > +static void mtk_uart_apdma_start_tx(struct mtk_chan *c) > > +{ > > + unsigned int len, send, left, wpt, d_wpt, tmp; > > + int ret; > > + > > + left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE); > > + if (!left) { > > + mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B); > > + return; > > + } > > + > > + /* Wait 1sec for flush, can't sleep*/ > > nit: one space after ',', period after 'sleep', space before '*'. > > > + ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp, > > + tmp != VFF_FLUSH_B, 0, 1000000); > > + if (ret) > > + dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n", > > + mtk_uart_apdma_read(c, VFF_DEBUG_STATUS)); > > Why do we need to wait for flush now? The previous implementation did > not require this... > because our HW buffer is cyclic. at one tx, if the size of data is bigger, data maybe cover. So must wait flush finish. confirm the data is right. like 128 bytes size, small length can't reproduce the issue. > > + > > + send = min_t(unsigned int, left, c->desc->avail_len); > > + wpt = mtk_uart_apdma_read(c, VFF_WPT); > > + len = mtk_uart_apdma_read(c, VFF_LEN); > > + > > + d_wpt = wpt + send; > > + if ((d_wpt & VFF_RING_SIZE) >= len) { > > I don't get why you need to add "& VFF_RING_SIZE". If wpt + send > > VFF_RING_SIZE, don't you need to toggle VFF_RING_WRAP too? the longest actual length is VFF_RING_SIZE. one cyclic, will set bit[16] to ~bit[16]. the bit[0 ~ 15] is actual address. So need get rid of bit[16] > > > + d_wpt = d_wpt - len; > > + d_wpt = d_wpt ^ VFF_RING_WRAP; > > + } > > + mtk_uart_apdma_write(c, VFF_WPT, d_wpt); > > + > > + c->desc->avail_len -= send; > > + > > + mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B); > > + if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U) > > + mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B); > > +} > > (thanks for the rest of the changes, this looks much more readable) > > > + ...... > > + > > +static int mtk_uart_apdma_device_pause(struct dma_chan *chan) > > +{ > > + /* just for check caps pass */ > > + return 0; > > +} > > This is still not right... Hopefully somebody more familiar with the > DMA subsystem can weigh in, but maybe it's enough to wait for the > current transfer to be flushed and temporarily disable interrupts? > e.g. call mtk_uart_apdma_terminate_all above? > i had review the 8250 UART framework. just check the function pointer, not use. and our HW can't support the feature. So i just keep it at first version. > > + > > +static int mtk_uart_apdma_device_resume(struct dma_chan *chan) > > +{ > > + /* just for check caps pass */ > > + return 0; > > +} > > Drop this one since you don't really need it. > ok, i will remove it. > > + > > +static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd) > > +{ > > + while (list_empty(&mtkd->ddev.channels) == 0) { > > !list_empty( > > > + struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels, > > + struct mtk_chan, vc.chan.device_node); > > + > > + list_del(&c->vc.chan.device_node); > > + tasklet_kill(&c->vc.task); > > + } > > +} > > + > > +static const struct of_device_id mtk_uart_apdma_match[] = { > > + { .compatible = "mediatek,mt6577-uart-dma", }, > > + { /* sentinel */ }, > > +}; > > +MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match); > > + > > +static int mtk_uart_apdma_probe(struct platform_device *pdev) > > +{ > > + struct mtk_uart_apdmadev *mtkd; > > + struct resource *res; > > + struct mtk_chan *c; > > + unsigned int i; > > + int rc; > > + > > + mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL); > > + if (!mtkd) > > + return -ENOMEM; > > + > > + mtkd->clk = devm_clk_get(&pdev->dev, NULL); > > + if (IS_ERR(mtkd->clk)) { > > + dev_err(&pdev->dev, "No clock specified\n"); > > + rc = PTR_ERR(mtkd->clk); > > + return rc; > > + } > > + > > + if (of_property_read_bool(pdev->dev.of_node, "dma-33bits")) > > + mtkd->support_33bits = true; > > I don't think this should be a device tree property. Typically we'd > have multiple compatible strings for (slightly) different HW blocks, > and enable 33bits only on HW that have support. > > See how it's done in drivers/i2c/busses/i2c-mt65xx.c, for example. > in MediaTek, not all IC can support 33bit. So i want to configure by DT. So don't need to modify code in New IC. > > + > > + rc = dma_set_mask_and_coherent(&pdev->dev, > > + DMA_BIT_MASK(32 | mtkd->support_33bits)); > > I'd feel a little more confortable if you used a variable instead: > > int dma_bits = 32; > > if (support_33bits) > dma_bits = 33; > > ..., DMA_BIT_MASK(dma_bits)); > OK, i can modify it. thanks. > > + if (rc) > > + return rc; > > + > > + dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask); > > + mtkd->ddev.device_alloc_chan_resources = > > + mtk_uart_apdma_alloc_chan_resources; > > + mtkd->ddev.device_free_chan_resources = > > + mtk_uart_apdma_free_chan_resources; > > + mtkd->ddev.device_tx_status = mtk_uart_apdma_tx_status; > > + mtkd->ddev.device_issue_pending = mtk_uart_apdma_issue_pending; > > + mtkd->ddev.device_prep_slave_sg = mtk_uart_apdma_prep_slave_sg; > > + mtkd->ddev.device_config = mtk_uart_apdma_slave_config; > > + mtkd->ddev.device_pause = mtk_uart_apdma_device_pause; > > + mtkd->ddev.device_resume = mtk_uart_apdma_device_resume; > > + mtkd->ddev.device_terminate_all = mtk_uart_apdma_terminate_all; > > + mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE); > > + mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE); > > + mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); > > + mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; > > + mtkd->ddev.dev = &pdev->dev; > > + INIT_LIST_HEAD(&mtkd->ddev.channels); > > + > > + for (i = 0; i < MTK_UART_APDMA_CHANNELS; i++) { > > + c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL); > > + if (!c) { > > + rc = -ENODEV; > > + goto err_no_dma; > > + } > > + > > + res = platform_get_resource(pdev, IORESOURCE_MEM, i); > > + if (!res) { > > + rc = -ENODEV; > > + goto err_no_dma; > > + } > > + > > + c->base = devm_ioremap_resource(&pdev->dev, res); > > + if (IS_ERR(c->base)) { > > + rc = PTR_ERR(c->base); > > + goto err_no_dma; > > + } > > + c->requested = false; > > + c->vc.desc_free = mtk_uart_apdma_desc_free; > > + vchan_init(&c->vc, &mtkd->ddev); > > + > > + mtkd->dma_irq[i] = platform_get_irq(pdev, i); > > + if ((int)mtkd->dma_irq[i] < 0) { > > + dev_err(&pdev->dev, "failed to get IRQ[%d]\n", i); > > + rc = -EINVAL; > > + goto err_no_dma; > > + } > > + } > > + > > + pm_runtime_enable(&pdev->dev); > > + pm_runtime_set_active(&pdev->dev); > > + > > + rc = dma_async_device_register(&mtkd->ddev); > > + if (rc) > > + goto rpm_disable; > > + > > + platform_set_drvdata(pdev, mtkd); > > + > > + if (pdev->dev.of_node) { > > + /* Device-tree DMA controller registration */ > > + rc = of_dma_controller_register(pdev->dev.of_node, > > + of_dma_xlate_by_chan_id, > > + mtkd); > > + if (rc) > > + goto dma_remove; > > + } > > + > > + return rc; > > + > > +dma_remove: > > + dma_async_device_unregister(&mtkd->ddev); > > +rpm_disable: > > + pm_runtime_disable(&pdev->dev); > > +err_no_dma: > > + mtk_uart_apdma_free(mtkd); > > + return rc; > > +} > > + ...... From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E14FC43387 for ; Thu, 10 Jan 2019 08:25:05 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C61D320675 for ; Thu, 10 Jan 2019 08:25:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="OfRMMecj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C61D320675 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Date:To:From:Subject:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=2mrKPsbbj+dsG/o4/UaqXX9lH3wTV3BAWEPT8NJdbHc=; b=OfRMMecjl+VXGQ vdqweoxjB/Pc+ZtEkNryjmO6npuCTBXlojirVaTV3x9iAI81dCq5P7JwYGgkaPXIc37eOaS0metQO J7Vqlz9VxZFudl7Ymq59zz98+/nTwI1RP4SUY766DRV9aSFdkIJozGM8xYUIvqfWaVyRsTlhPKy8s /vseXnYkRos8rgLqshHl3lDBSw3QKjF8Qlt/Kd4SSskwlgM7nS44R3ea/Ilckxclbkrjf6fwB3wvP XQvFcNn/nn0nul91SwEh74g2TZLjAgPWQK0z/YDNmiZ0aLbS/mWQAX6Cwub9oqOfWD7HieOSy0oQG BcyAMDuwreuxyGLZQqWg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1ghVeB-0001uz-SN; Thu, 10 Jan 2019 08:25:03 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1ghVe6-0001u4-Gv; Thu, 10 Jan 2019 08:25:00 +0000 X-UUID: 74bcb2c7e85048d9a06e7a526433dc65-20190110 X-UUID: 74bcb2c7e85048d9a06e7a526433dc65-20190110 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 1677422035; Thu, 10 Jan 2019 00:24:49 -0800 Received: from MTKMBS01N1.mediatek.inc (172.21.101.68) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Thu, 10 Jan 2019 00:24:48 -0800 Received: from MTKCAS32.mediatek.inc (172.27.4.184) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Thu, 10 Jan 2019 16:24:46 +0800 Received: from [10.17.3.153] (10.17.3.153) by MTKCAS32.mediatek.inc (172.27.4.170) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Thu, 10 Jan 2019 16:24:45 +0800 Message-ID: <1547108685.3831.21.camel@mhfsdcap03> Subject: Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support From: Long Cheng To: Nicolas Boichat Date: Thu, 10 Jan 2019 16:24:45 +0800 In-Reply-To: References: <1546395178-8880-1-git-send-email-long.cheng@mediatek.com> <1546395178-8880-2-git-send-email-long.cheng@mediatek.com> X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190110_002458_563706_3BCA08FB X-CRM114-Status: GOOD ( 24.95 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Sean Wang , Zhenbao Liu , Ryder Lee , Long Cheng , linux-serial@vger.kernel.org, Jiri Slaby , YT Shen , Yingjoe Chen , devicetree@vger.kernel.org, Sean Wang , Rob Herring , linux-mediatek@lists.infradead.org, Matthias Brugger , Dan Williams , linux-arm Mailing List , srv_heupstream@mediatek.com, Greg Kroah-Hartman , Randy Dunlap , lkml , Vinod Koul , dmaengine@vger.kernel.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Thu, 2019-01-03 at 09:39 +0800, Nicolas Boichat wrote: > On Wed, Jan 2, 2019 at 10:13 AM Long Cheng wrote: > > ..... > > +/* interrupt trigger level for tx */ > > +#define VFF_TX_THRE(n) ((n) * 7 / 8) > > +/* interrupt trigger level for rx */ > > +#define VFF_RX_THRE(n) ((n) * 3 / 4) > > + > > +#define VFF_RING_SIZE 0xffffU > > Well, the size is actually 0x10000. Maybe call this VFF_RING_SIZE_MASK? > the max length is 0xffff. the bit 16 is wrap bit. our buffer is ring buffer. So not mask. > > +/* invert this bit when wrap ring head again*/ > > +#define VFF_RING_WRAP 0x10000U > > + > > + writel(val, c->base + reg); > > +} > > + ...... > > +static void mtk_uart_apdma_start_tx(struct mtk_chan *c) > > +{ > > + unsigned int len, send, left, wpt, d_wpt, tmp; > > + int ret; > > + > > + left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE); > > + if (!left) { > > + mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B); > > + return; > > + } > > + > > + /* Wait 1sec for flush, can't sleep*/ > > nit: one space after ',', period after 'sleep', space before '*'. > > > + ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp, > > + tmp != VFF_FLUSH_B, 0, 1000000); > > + if (ret) > > + dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n", > > + mtk_uart_apdma_read(c, VFF_DEBUG_STATUS)); > > Why do we need to wait for flush now? The previous implementation did > not require this... > because our HW buffer is cyclic. at one tx, if the size of data is bigger, data maybe cover. So must wait flush finish. confirm the data is right. like 128 bytes size, small length can't reproduce the issue. > > + > > + send = min_t(unsigned int, left, c->desc->avail_len); > > + wpt = mtk_uart_apdma_read(c, VFF_WPT); > > + len = mtk_uart_apdma_read(c, VFF_LEN); > > + > > + d_wpt = wpt + send; > > + if ((d_wpt & VFF_RING_SIZE) >= len) { > > I don't get why you need to add "& VFF_RING_SIZE". If wpt + send > > VFF_RING_SIZE, don't you need to toggle VFF_RING_WRAP too? the longest actual length is VFF_RING_SIZE. one cyclic, will set bit[16] to ~bit[16]. the bit[0 ~ 15] is actual address. So need get rid of bit[16] > > > + d_wpt = d_wpt - len; > > + d_wpt = d_wpt ^ VFF_RING_WRAP; > > + } > > + mtk_uart_apdma_write(c, VFF_WPT, d_wpt); > > + > > + c->desc->avail_len -= send; > > + > > + mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B); > > + if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U) > > + mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B); > > +} > > (thanks for the rest of the changes, this looks much more readable) > > > + ...... > > + > > +static int mtk_uart_apdma_device_pause(struct dma_chan *chan) > > +{ > > + /* just for check caps pass */ > > + return 0; > > +} > > This is still not right... Hopefully somebody more familiar with the > DMA subsystem can weigh in, but maybe it's enough to wait for the > current transfer to be flushed and temporarily disable interrupts? > e.g. call mtk_uart_apdma_terminate_all above? > i had review the 8250 UART framework. just check the function pointer, not use. and our HW can't support the feature. So i just keep it at first version. > > + > > +static int mtk_uart_apdma_device_resume(struct dma_chan *chan) > > +{ > > + /* just for check caps pass */ > > + return 0; > > +} > > Drop this one since you don't really need it. > ok, i will remove it. > > + > > +static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd) > > +{ > > + while (list_empty(&mtkd->ddev.channels) == 0) { > > !list_empty( > > > + struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels, > > + struct mtk_chan, vc.chan.device_node); > > + > > + list_del(&c->vc.chan.device_node); > > + tasklet_kill(&c->vc.task); > > + } > > +} > > + > > +static const struct of_device_id mtk_uart_apdma_match[] = { > > + { .compatible = "mediatek,mt6577-uart-dma", }, > > + { /* sentinel */ }, > > +}; > > +MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match); > > + > > +static int mtk_uart_apdma_probe(struct platform_device *pdev) > > +{ > > + struct mtk_uart_apdmadev *mtkd; > > + struct resource *res; > > + struct mtk_chan *c; > > + unsigned int i; > > + int rc; > > + > > + mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL); > > + if (!mtkd) > > + return -ENOMEM; > > + > > + mtkd->clk = devm_clk_get(&pdev->dev, NULL); > > + if (IS_ERR(mtkd->clk)) { > > + dev_err(&pdev->dev, "No clock specified\n"); > > + rc = PTR_ERR(mtkd->clk); > > + return rc; > > + } > > + > > + if (of_property_read_bool(pdev->dev.of_node, "dma-33bits")) > > + mtkd->support_33bits = true; > > I don't think this should be a device tree property. Typically we'd > have multiple compatible strings for (slightly) different HW blocks, > and enable 33bits only on HW that have support. > > See how it's done in drivers/i2c/busses/i2c-mt65xx.c, for example. > in MediaTek, not all IC can support 33bit. So i want to configure by DT. So don't need to modify code in New IC. > > + > > + rc = dma_set_mask_and_coherent(&pdev->dev, > > + DMA_BIT_MASK(32 | mtkd->support_33bits)); > > I'd feel a little more confortable if you used a variable instead: > > int dma_bits = 32; > > if (support_33bits) > dma_bits = 33; > > ..., DMA_BIT_MASK(dma_bits)); > OK, i can modify it. thanks. > > + if (rc) > > + return rc; > > + > > + dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask); > > + mtkd->ddev.device_alloc_chan_resources = > > + mtk_uart_apdma_alloc_chan_resources; > > + mtkd->ddev.device_free_chan_resources = > > + mtk_uart_apdma_free_chan_resources; > > + mtkd->ddev.device_tx_status = mtk_uart_apdma_tx_status; > > + mtkd->ddev.device_issue_pending = mtk_uart_apdma_issue_pending; > > + mtkd->ddev.device_prep_slave_sg = mtk_uart_apdma_prep_slave_sg; > > + mtkd->ddev.device_config = mtk_uart_apdma_slave_config; > > + mtkd->ddev.device_pause = mtk_uart_apdma_device_pause; > > + mtkd->ddev.device_resume = mtk_uart_apdma_device_resume; > > + mtkd->ddev.device_terminate_all = mtk_uart_apdma_terminate_all; > > + mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE); > > + mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE); > > + mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); > > + mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; > > + mtkd->ddev.dev = &pdev->dev; > > + INIT_LIST_HEAD(&mtkd->ddev.channels); > > + > > + for (i = 0; i < MTK_UART_APDMA_CHANNELS; i++) { > > + c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL); > > + if (!c) { > > + rc = -ENODEV; > > + goto err_no_dma; > > + } > > + > > + res = platform_get_resource(pdev, IORESOURCE_MEM, i); > > + if (!res) { > > + rc = -ENODEV; > > + goto err_no_dma; > > + } > > + > > + c->base = devm_ioremap_resource(&pdev->dev, res); > > + if (IS_ERR(c->base)) { > > + rc = PTR_ERR(c->base); > > + goto err_no_dma; > > + } > > + c->requested = false; > > + c->vc.desc_free = mtk_uart_apdma_desc_free; > > + vchan_init(&c->vc, &mtkd->ddev); > > + > > + mtkd->dma_irq[i] = platform_get_irq(pdev, i); > > + if ((int)mtkd->dma_irq[i] < 0) { > > + dev_err(&pdev->dev, "failed to get IRQ[%d]\n", i); > > + rc = -EINVAL; > > + goto err_no_dma; > > + } > > + } > > + > > + pm_runtime_enable(&pdev->dev); > > + pm_runtime_set_active(&pdev->dev); > > + > > + rc = dma_async_device_register(&mtkd->ddev); > > + if (rc) > > + goto rpm_disable; > > + > > + platform_set_drvdata(pdev, mtkd); > > + > > + if (pdev->dev.of_node) { > > + /* Device-tree DMA controller registration */ > > + rc = of_dma_controller_register(pdev->dev.of_node, > > + of_dma_xlate_by_chan_id, > > + mtkd); > > + if (rc) > > + goto dma_remove; > > + } > > + > > + return rc; > > + > > +dma_remove: > > + dma_async_device_unregister(&mtkd->ddev); > > +rpm_disable: > > + pm_runtime_disable(&pdev->dev); > > +err_no_dma: > > + mtk_uart_apdma_free(mtkd); > > + return rc; > > +} > > + ...... _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_PASS,UNPARSEABLE_RELAY,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD1B8C43387 for ; Thu, 10 Jan 2019 08:24:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7E94420675 for ; Thu, 10 Jan 2019 08:24:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727675AbfAJIY4 (ORCPT ); Thu, 10 Jan 2019 03:24:56 -0500 Received: from mailgw01.mediatek.com ([210.61.82.183]:53157 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727262AbfAJIYz (ORCPT ); Thu, 10 Jan 2019 03:24:55 -0500 X-UUID: b48ebcbf60974a43ad01e0954853a00a-20190110 X-UUID: b48ebcbf60974a43ad01e0954853a00a-20190110 Received: from mtkexhb01.mediatek.inc [(172.21.101.102)] by mailgw01.mediatek.com (envelope-from ) (mhqrelay.mediatek.com ESMTP with TLS) with ESMTP id 650511360; Thu, 10 Jan 2019 16:24:47 +0800 Received: from MTKCAS32.mediatek.inc (172.27.4.184) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Thu, 10 Jan 2019 16:24:46 +0800 Received: from [10.17.3.153] (10.17.3.153) by MTKCAS32.mediatek.inc (172.27.4.170) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Thu, 10 Jan 2019 16:24:45 +0800 Message-ID: <1547108685.3831.21.camel@mhfsdcap03> Subject: Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support From: Long Cheng To: Nicolas Boichat CC: Vinod Koul , Randy Dunlap , "Rob Herring" , Mark Rutland , "Ryder Lee" , Sean Wang , "Matthias Brugger" , Dan Williams , Greg Kroah-Hartman , Jiri Slaby , Sean Wang , , , "linux-arm Mailing List" , , lkml , , , Yingjoe Chen , YT Shen , Zhenbao Liu , Long Cheng Date: Thu, 10 Jan 2019 16:24:45 +0800 In-Reply-To: References: <1546395178-8880-1-git-send-email-long.cheng@mediatek.com> <1546395178-8880-2-git-send-email-long.cheng@mediatek.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.2.3-0ubuntu6 Content-Transfer-Encoding: 7bit MIME-Version: 1.0 X-MTK: N Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 2019-01-03 at 09:39 +0800, Nicolas Boichat wrote: > On Wed, Jan 2, 2019 at 10:13 AM Long Cheng wrote: > > ..... > > +/* interrupt trigger level for tx */ > > +#define VFF_TX_THRE(n) ((n) * 7 / 8) > > +/* interrupt trigger level for rx */ > > +#define VFF_RX_THRE(n) ((n) * 3 / 4) > > + > > +#define VFF_RING_SIZE 0xffffU > > Well, the size is actually 0x10000. Maybe call this VFF_RING_SIZE_MASK? > the max length is 0xffff. the bit 16 is wrap bit. our buffer is ring buffer. So not mask. > > +/* invert this bit when wrap ring head again*/ > > +#define VFF_RING_WRAP 0x10000U > > + > > + writel(val, c->base + reg); > > +} > > + ...... > > +static void mtk_uart_apdma_start_tx(struct mtk_chan *c) > > +{ > > + unsigned int len, send, left, wpt, d_wpt, tmp; > > + int ret; > > + > > + left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE); > > + if (!left) { > > + mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B); > > + return; > > + } > > + > > + /* Wait 1sec for flush, can't sleep*/ > > nit: one space after ',', period after 'sleep', space before '*'. > > > + ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp, > > + tmp != VFF_FLUSH_B, 0, 1000000); > > + if (ret) > > + dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n", > > + mtk_uart_apdma_read(c, VFF_DEBUG_STATUS)); > > Why do we need to wait for flush now? The previous implementation did > not require this... > because our HW buffer is cyclic. at one tx, if the size of data is bigger, data maybe cover. So must wait flush finish. confirm the data is right. like 128 bytes size, small length can't reproduce the issue. > > + > > + send = min_t(unsigned int, left, c->desc->avail_len); > > + wpt = mtk_uart_apdma_read(c, VFF_WPT); > > + len = mtk_uart_apdma_read(c, VFF_LEN); > > + > > + d_wpt = wpt + send; > > + if ((d_wpt & VFF_RING_SIZE) >= len) { > > I don't get why you need to add "& VFF_RING_SIZE". If wpt + send > > VFF_RING_SIZE, don't you need to toggle VFF_RING_WRAP too? the longest actual length is VFF_RING_SIZE. one cyclic, will set bit[16] to ~bit[16]. the bit[0 ~ 15] is actual address. So need get rid of bit[16] > > > + d_wpt = d_wpt - len; > > + d_wpt = d_wpt ^ VFF_RING_WRAP; > > + } > > + mtk_uart_apdma_write(c, VFF_WPT, d_wpt); > > + > > + c->desc->avail_len -= send; > > + > > + mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B); > > + if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U) > > + mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B); > > +} > > (thanks for the rest of the changes, this looks much more readable) > > > + ...... > > + > > +static int mtk_uart_apdma_device_pause(struct dma_chan *chan) > > +{ > > + /* just for check caps pass */ > > + return 0; > > +} > > This is still not right... Hopefully somebody more familiar with the > DMA subsystem can weigh in, but maybe it's enough to wait for the > current transfer to be flushed and temporarily disable interrupts? > e.g. call mtk_uart_apdma_terminate_all above? > i had review the 8250 UART framework. just check the function pointer, not use. and our HW can't support the feature. So i just keep it at first version. > > + > > +static int mtk_uart_apdma_device_resume(struct dma_chan *chan) > > +{ > > + /* just for check caps pass */ > > + return 0; > > +} > > Drop this one since you don't really need it. > ok, i will remove it. > > + > > +static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd) > > +{ > > + while (list_empty(&mtkd->ddev.channels) == 0) { > > !list_empty( > > > + struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels, > > + struct mtk_chan, vc.chan.device_node); > > + > > + list_del(&c->vc.chan.device_node); > > + tasklet_kill(&c->vc.task); > > + } > > +} > > + > > +static const struct of_device_id mtk_uart_apdma_match[] = { > > + { .compatible = "mediatek,mt6577-uart-dma", }, > > + { /* sentinel */ }, > > +}; > > +MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match); > > + > > +static int mtk_uart_apdma_probe(struct platform_device *pdev) > > +{ > > + struct mtk_uart_apdmadev *mtkd; > > + struct resource *res; > > + struct mtk_chan *c; > > + unsigned int i; > > + int rc; > > + > > + mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL); > > + if (!mtkd) > > + return -ENOMEM; > > + > > + mtkd->clk = devm_clk_get(&pdev->dev, NULL); > > + if (IS_ERR(mtkd->clk)) { > > + dev_err(&pdev->dev, "No clock specified\n"); > > + rc = PTR_ERR(mtkd->clk); > > + return rc; > > + } > > + > > + if (of_property_read_bool(pdev->dev.of_node, "dma-33bits")) > > + mtkd->support_33bits = true; > > I don't think this should be a device tree property. Typically we'd > have multiple compatible strings for (slightly) different HW blocks, > and enable 33bits only on HW that have support. > > See how it's done in drivers/i2c/busses/i2c-mt65xx.c, for example. > in MediaTek, not all IC can support 33bit. So i want to configure by DT. So don't need to modify code in New IC. > > + > > + rc = dma_set_mask_and_coherent(&pdev->dev, > > + DMA_BIT_MASK(32 | mtkd->support_33bits)); > > I'd feel a little more confortable if you used a variable instead: > > int dma_bits = 32; > > if (support_33bits) > dma_bits = 33; > > ..., DMA_BIT_MASK(dma_bits)); > OK, i can modify it. thanks. > > + if (rc) > > + return rc; > > + > > + dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask); > > + mtkd->ddev.device_alloc_chan_resources = > > + mtk_uart_apdma_alloc_chan_resources; > > + mtkd->ddev.device_free_chan_resources = > > + mtk_uart_apdma_free_chan_resources; > > + mtkd->ddev.device_tx_status = mtk_uart_apdma_tx_status; > > + mtkd->ddev.device_issue_pending = mtk_uart_apdma_issue_pending; > > + mtkd->ddev.device_prep_slave_sg = mtk_uart_apdma_prep_slave_sg; > > + mtkd->ddev.device_config = mtk_uart_apdma_slave_config; > > + mtkd->ddev.device_pause = mtk_uart_apdma_device_pause; > > + mtkd->ddev.device_resume = mtk_uart_apdma_device_resume; > > + mtkd->ddev.device_terminate_all = mtk_uart_apdma_terminate_all; > > + mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE); > > + mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE); > > + mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); > > + mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; > > + mtkd->ddev.dev = &pdev->dev; > > + INIT_LIST_HEAD(&mtkd->ddev.channels); > > + > > + for (i = 0; i < MTK_UART_APDMA_CHANNELS; i++) { > > + c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL); > > + if (!c) { > > + rc = -ENODEV; > > + goto err_no_dma; > > + } > > + > > + res = platform_get_resource(pdev, IORESOURCE_MEM, i); > > + if (!res) { > > + rc = -ENODEV; > > + goto err_no_dma; > > + } > > + > > + c->base = devm_ioremap_resource(&pdev->dev, res); > > + if (IS_ERR(c->base)) { > > + rc = PTR_ERR(c->base); > > + goto err_no_dma; > > + } > > + c->requested = false; > > + c->vc.desc_free = mtk_uart_apdma_desc_free; > > + vchan_init(&c->vc, &mtkd->ddev); > > + > > + mtkd->dma_irq[i] = platform_get_irq(pdev, i); > > + if ((int)mtkd->dma_irq[i] < 0) { > > + dev_err(&pdev->dev, "failed to get IRQ[%d]\n", i); > > + rc = -EINVAL; > > + goto err_no_dma; > > + } > > + } > > + > > + pm_runtime_enable(&pdev->dev); > > + pm_runtime_set_active(&pdev->dev); > > + > > + rc = dma_async_device_register(&mtkd->ddev); > > + if (rc) > > + goto rpm_disable; > > + > > + platform_set_drvdata(pdev, mtkd); > > + > > + if (pdev->dev.of_node) { > > + /* Device-tree DMA controller registration */ > > + rc = of_dma_controller_register(pdev->dev.of_node, > > + of_dma_xlate_by_chan_id, > > + mtkd); > > + if (rc) > > + goto dma_remove; > > + } > > + > > + return rc; > > + > > +dma_remove: > > + dma_async_device_unregister(&mtkd->ddev); > > +rpm_disable: > > + pm_runtime_disable(&pdev->dev); > > +err_no_dma: > > + mtk_uart_apdma_free(mtkd); > > + return rc; > > +} > > + ......