From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mark yao Subject: Re: [PATCH v5 6/8] drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain Date: Fri, 8 Jul 2016 08:54:53 +0800 Message-ID: <577EF9DD.1010506@rock-chips.com> References: <1466734413-7453-1-git-send-email-zhengsq@rock-chips.com> <1466734413-7453-7-git-send-email-zhengsq@rock-chips.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1466734413-7453-7-git-send-email-zhengsq@rock-chips.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Shunqian Zheng , joro@8bytes.org, heiko@sntech.de, robh+dt@kernel.org, mark.rutland@arm.com, linux@armlinux.org.uk, airlied@linux.ie, tfiga@google.com, xxm@rock-chips.com Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Tomasz Figa , linux-rockchip@lists.infradead.org, iommu@lists.linux-foundation.org, linux-arm-kernel@lists.infradead.org List-Id: iommu@lists.linux-foundation.org T24gMjAxNuW5tDA25pyIMjTml6UgMTA6MTMsIFNodW5xaWFuIFpoZW5nIHdyb3RlOgo+IEZyb206 IFRvbWFzeiBGaWdhIDx0ZmlnYUBjaHJvbWl1bS5vcmc+Cj4KPiBUaGUgQVBJIGlzIG5vdCBzdWl0 YWJsZSBmb3Igc3Vic3lzdGVtcyBjb25zaXN0aW5nIG9mIG11bHRpcGxlIGRldmljZXMKPiBhbmQg cmVxdWlyZXMgc2V2ZXJlIGhhY2tzIHRvIHVzZSBpdC4gVG8gbWl0aWdhdGUgdGhpcywgdGhpcyBw YXRjaAo+IGltcGxlbWVudHMgYWxsb2NhdGlvbiBhbmQgYWRkcmVzcyBzcGFjZSBtYW5hZ2VtZW50 IGxvY2FsbHkgYnkgdXNpbmcKPiBoZWxwZXJzIHByb3ZpZGVkIGJ5IERSTSBmcmFtZXdvcmssIGxp a2Ugb3RoZXIgRFJNIGRyaXZlcnMgZG8sIGUuZy4KPiBUZWdyYS4KPgo+IFRoaXMgcGF0Y2ggc2hv dWxkIG5vdCBpbnRyb2R1Y2UgYW55IGZ1bmN0aW9uYWwgY2hhbmdlcyB1bnRpbCB0aGUgZHJpdmVy Cj4gaXMgbWFkZSB0byBhdHRhY2ggc3ViZGV2aWNlcyBpbnRvIGFuIElPTU1VIGRvbWFpbiB3aXRo IHRoZSBnZW5lcmljIElPTU1VCj4gQVBJLCB3aGljaCB3aWxsIGhhcHBlbiBpbiBmb2xsb3dpbmcg cGF0Y2guIEJhc2VkIGhlYXZpbHkgb24gR0VNCj4gaW1wbGVtZW50YXRpb24gb2YgVGVncmEgRFJN IGRyaXZlci4KCkFja2VkLWJ5OiBNYXJrIFlhbyA8bWFyay55YW9Acm9jay1jaGlwcy5jb20+Cj4K PiBTaWduZWQtb2ZmLWJ5OiBUb21hc3ogRmlnYSA8dGZpZ2FAY2hyb21pdW0ub3JnPgo+IFNpZ25l ZC1vZmYtYnk6IFNodW5xaWFuIFpoZW5nIDx6aGVuZ3NxQHJvY2stY2hpcHMuY29tPgo+IC0tLQo+ ICAgZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL3JvY2tjaGlwX2RybV9kcnYuaCB8ICAgMyArCj4g ICBkcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvcm9ja2NoaXBfZHJtX2dlbS5jIHwgMjIxICsrKysr KysrKysrKysrKysrKysrKysrKysrLS0KPiAgIGRyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9yb2Nr Y2hpcF9kcm1fZ2VtLmggfCAgIDkgKysKPiAgIDMgZmlsZXMgY2hhbmdlZCwgMjIyIGluc2VydGlv bnMoKyksIDExIGRlbGV0aW9ucygtKQo+Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9y b2NrY2hpcC9yb2NrY2hpcF9kcm1fZHJ2LmggYi9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvcm9j a2NoaXBfZHJtX2Rydi5oCj4gaW5kZXggZWEzOTMyOS4uNWFiMTIyMyAxMDA2NDQKPiAtLS0gYS9k cml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvcm9ja2NoaXBfZHJtX2Rydi5oCj4gKysrIGIvZHJpdmVy cy9ncHUvZHJtL3JvY2tjaGlwL3JvY2tjaGlwX2RybV9kcnYuaAo+IEBAIC0zMCw2ICszMCw3IEBA Cj4gICAKPiAgIHN0cnVjdCBkcm1fZGV2aWNlOwo+ICAgc3RydWN0IGRybV9jb25uZWN0b3I7Cj4g K3N0cnVjdCBpb21tdV9kb21haW47Cj4gICAKPiAgIC8qCj4gICAgKiBSb2NrY2hpcCBkcm0gcHJp dmF0ZSBjcnRjIGZ1bmNzLgo+IEBAIC02MSw2ICs2Miw4IEBAIHN0cnVjdCByb2NrY2hpcF9kcm1f cHJpdmF0ZSB7Cj4gICAJc3RydWN0IGRybV9nZW1fb2JqZWN0ICpmYmRldl9ibzsKPiAgIAljb25z dCBzdHJ1Y3Qgcm9ja2NoaXBfY3J0Y19mdW5jcyAqY3J0Y19mdW5jc1tST0NLQ0hJUF9NQVhfQ1JU Q107Cj4gICAJc3RydWN0IGRybV9hdG9taWNfc3RhdGUgKnN0YXRlOwo+ICsJc3RydWN0IGlvbW11 X2RvbWFpbiAqZG9tYWluOwo+ICsJc3RydWN0IGRybV9tbSBtbTsKPiAgIH07Cj4gICAKPiAgIGlu dCByb2NrY2hpcF9yZWdpc3Rlcl9jcnRjX2Z1bmNzKHN0cnVjdCBkcm1fY3J0YyAqY3J0YywKPiBk aWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL3JvY2tjaGlwX2RybV9nZW0uYyBi L2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9yb2NrY2hpcF9kcm1fZ2VtLmMKPiBpbmRleCAzOTRm OTJiLi5lN2NkOTNkIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9yb2Nr Y2hpcF9kcm1fZ2VtLmMKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvcm9ja2NoaXBf ZHJtX2dlbS5jCj4gQEAgLTE5LDExICsxOSwxMzUgQEAKPiAgICNpbmNsdWRlIDxkcm0vcm9ja2No aXBfZHJtLmg+Cj4gICAKPiAgICNpbmNsdWRlIDxsaW51eC9kbWEtYXR0cnMuaD4KPiArI2luY2x1 ZGUgPGxpbnV4L2lvbW11Lmg+Cj4gICAKPiAgICNpbmNsdWRlICJyb2NrY2hpcF9kcm1fZHJ2Lmgi Cj4gICAjaW5jbHVkZSAicm9ja2NoaXBfZHJtX2dlbS5oIgo+ICAgCj4gLXN0YXRpYyBpbnQgcm9j a2NoaXBfZ2VtX2FsbG9jX2J1ZihzdHJ1Y3Qgcm9ja2NoaXBfZ2VtX29iamVjdCAqcmtfb2JqLAo+ ICtzdGF0aWMgaW50IHJvY2tjaGlwX2dlbV9pb21tdV9tYXAoc3RydWN0IHJvY2tjaGlwX2dlbV9v YmplY3QgKnJrX29iaikKPiArewo+ICsJc3RydWN0IGRybV9kZXZpY2UgKmRybSA9IHJrX29iai0+ YmFzZS5kZXY7Cj4gKwlzdHJ1Y3Qgcm9ja2NoaXBfZHJtX3ByaXZhdGUgKnByaXZhdGUgPSBkcm0t PmRldl9wcml2YXRlOwo+ICsJaW50IHByb3QgPSBJT01NVV9SRUFEIHwgSU9NTVVfV1JJVEU7Cj4g Kwlzc2l6ZV90IHJldDsKPiArCj4gKwlyZXQgPSBkcm1fbW1faW5zZXJ0X25vZGVfZ2VuZXJpYygm cHJpdmF0ZS0+bW0sICZya19vYmotPm1tLAo+ICsJCQkJCSBya19vYmotPmJhc2Uuc2l6ZSwgUEFH RV9TSVpFLAo+ICsJCQkJCSAwLCAwLCAwKTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJRFJNX0VS Uk9SKCJvdXQgb2YgSS9PIHZpcnR1YWwgbWVtb3J5OiAlemRcbiIsIHJldCk7Cj4gKwkJcmV0dXJu IHJldDsKPiArCX0KPiArCj4gKwlya19vYmotPmRtYV9hZGRyID0gcmtfb2JqLT5tbS5zdGFydDsK PiArCj4gKwlyZXQgPSBpb21tdV9tYXBfc2cocHJpdmF0ZS0+ZG9tYWluLCBya19vYmotPmRtYV9h ZGRyLCBya19vYmotPnNndC0+c2dsLAo+ICsJCQkgICBya19vYmotPnNndC0+bmVudHMsIHByb3Qp Owo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlEUk1fRVJST1IoImZhaWxlZCB0byBtYXAgYnVmZmVy OiAlemRcbiIsIHJldCk7Cj4gKwkJZ290byBlcnJfcmVtb3ZlX25vZGU7Cj4gKwl9Cj4gKwo+ICsJ cmtfb2JqLT5zaXplID0gcmV0Owo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArZXJyX3JlbW92ZV9u b2RlOgo+ICsJZHJtX21tX3JlbW92ZV9ub2RlKCZya19vYmotPm1tKTsKPiArCj4gKwlyZXR1cm4g cmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHJvY2tjaGlwX2dlbV9pb21tdV91bm1hcChzdHJ1 Y3Qgcm9ja2NoaXBfZ2VtX29iamVjdCAqcmtfb2JqKQo+ICt7Cj4gKwlzdHJ1Y3QgZHJtX2Rldmlj ZSAqZHJtID0gcmtfb2JqLT5iYXNlLmRldjsKPiArCXN0cnVjdCByb2NrY2hpcF9kcm1fcHJpdmF0 ZSAqcHJpdmF0ZSA9IGRybS0+ZGV2X3ByaXZhdGU7Cj4gKwo+ICsJaW9tbXVfdW5tYXAocHJpdmF0 ZS0+ZG9tYWluLCBya19vYmotPmRtYV9hZGRyLCBya19vYmotPnNpemUpOwo+ICsJZHJtX21tX3Jl bW92ZV9ub2RlKCZya19vYmotPm1tKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3Rh dGljIGludCByb2NrY2hpcF9nZW1fZ2V0X3BhZ2VzKHN0cnVjdCByb2NrY2hpcF9nZW1fb2JqZWN0 ICpya19vYmopCj4gK3sKPiArCXN0cnVjdCBkcm1fZGV2aWNlICpkcm0gPSBya19vYmotPmJhc2Uu ZGV2Owo+ICsJaW50IHJldCwgaTsKPiArCXN0cnVjdCBzY2F0dGVybGlzdCAqczsKPiArCj4gKwly a19vYmotPnBhZ2VzID0gZHJtX2dlbV9nZXRfcGFnZXMoJnJrX29iai0+YmFzZSk7Cj4gKwlpZiAo SVNfRVJSKHJrX29iai0+cGFnZXMpKQo+ICsJCXJldHVybiBQVFJfRVJSKHJrX29iai0+cGFnZXMp Owo+ICsKPiArCXJrX29iai0+bnVtX3BhZ2VzID0gcmtfb2JqLT5iYXNlLnNpemUgPj4gUEFHRV9T SElGVDsKPiArCj4gKwlya19vYmotPnNndCA9IGRybV9wcmltZV9wYWdlc190b19zZyhya19vYmot PnBhZ2VzLCBya19vYmotPm51bV9wYWdlcyk7Cj4gKwlpZiAoSVNfRVJSKHJrX29iai0+c2d0KSkg ewo+ICsJCXJldCA9IFBUUl9FUlIocmtfb2JqLT5zZ3QpOwo+ICsJCWdvdG8gZXJyX3B1dF9wYWdl czsKPiArCX0KPiArCj4gKwkvKgo+ICsJICogRmFrZSB1cCB0aGUgU0cgdGFibGUgc28gdGhhdCBk bWFfc3luY19zZ19mb3JfZGV2aWNlKCkgY2FuIGJlIHVzZWQKPiArCSAqIHRvIGZsdXNoIHRoZSBw YWdlcyBhc3NvY2lhdGVkIHdpdGggaXQuCj4gKwkgKgo+ICsJICogVE9ETzogUmVwbGFjZSB0aGlz IGJ5IGRybV9jbGZsdXNoX3NnKCkgb25jZSBpdCBjYW4gYmUgaW1wbGVtZW50ZWQKPiArCSAqIHdp dGhvdXQgcmVseWluZyBvbiBzeW1ib2xzIHRoYXQgYXJlIG5vdCBleHBvcnRlZC4KPiArCSAqLwo+ ICsJZm9yX2VhY2hfc2cocmtfb2JqLT5zZ3QtPnNnbCwgcywgcmtfb2JqLT5zZ3QtPm5lbnRzLCBp KQo+ICsJCXNnX2RtYV9hZGRyZXNzKHMpID0gc2dfcGh5cyhzKTsKPiArCj4gKwlkbWFfc3luY19z Z19mb3JfZGV2aWNlKGRybS0+ZGV2LCBya19vYmotPnNndC0+c2dsLCBya19vYmotPnNndC0+bmVu dHMsCj4gKwkJCSAgICAgICBETUFfVE9fREVWSUNFKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArCj4g K2Vycl9wdXRfcGFnZXM6Cj4gKwlkcm1fZ2VtX3B1dF9wYWdlcygmcmtfb2JqLT5iYXNlLCBya19v YmotPnBhZ2VzLCBmYWxzZSwgZmFsc2UpOwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3Rh dGljIHZvaWQgcm9ja2NoaXBfZ2VtX3B1dF9wYWdlcyhzdHJ1Y3Qgcm9ja2NoaXBfZ2VtX29iamVj dCAqcmtfb2JqKQo+ICt7Cj4gKwlzZ19mcmVlX3RhYmxlKHJrX29iai0+c2d0KTsKPiArCWtmcmVl KHJrX29iai0+c2d0KTsKPiArCWRybV9nZW1fcHV0X3BhZ2VzKCZya19vYmotPmJhc2UsIHJrX29i ai0+cGFnZXMsIGZhbHNlLCBmYWxzZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgcm9ja2NoaXBf Z2VtX2FsbG9jX2lvbW11KHN0cnVjdCByb2NrY2hpcF9nZW1fb2JqZWN0ICpya19vYmosCj4gKwkJ CQkgICAgYm9vbCBhbGxvY19rbWFwKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IHJv Y2tjaGlwX2dlbV9nZXRfcGFnZXMocmtfb2JqKTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCXJldHVy biByZXQ7Cj4gKwo+ICsJcmV0ID0gcm9ja2NoaXBfZ2VtX2lvbW11X21hcChya19vYmopOwo+ICsJ aWYgKHJldCA8IDApCj4gKwkJZ290byBlcnJfZnJlZTsKPiArCj4gKwlpZiAoYWxsb2Nfa21hcCkg ewo+ICsJCXJrX29iai0+a3ZhZGRyID0gdm1hcChya19vYmotPnBhZ2VzLCBya19vYmotPm51bV9w YWdlcywgVk1fTUFQLAo+ICsJCQkJICAgICAgcGdwcm90X3dyaXRlY29tYmluZShQQUdFX0tFUk5F TCkpOwo+ICsJCWlmICghcmtfb2JqLT5rdmFkZHIpIHsKPiArCQkJRFJNX0VSUk9SKCJmYWlsZWQg dG8gdm1hcCgpIGJ1ZmZlclxuIik7Cj4gKwkJCXJldCA9IC1FTk9NRU07Cj4gKwkJCWdvdG8gZXJy X3VubWFwOwo+ICsJCX0KPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArCj4gK2Vycl91bm1hcDoK PiArCXJvY2tjaGlwX2dlbV9pb21tdV91bm1hcChya19vYmopOwo+ICtlcnJfZnJlZToKPiArCXJv Y2tjaGlwX2dlbV9wdXRfcGFnZXMocmtfb2JqKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4g Kwo+ICtzdGF0aWMgaW50IHJvY2tjaGlwX2dlbV9hbGxvY19kbWEoc3RydWN0IHJvY2tjaGlwX2dl bV9vYmplY3QgKnJrX29iaiwKPiAgIAkJCQkgIGJvb2wgYWxsb2Nfa21hcCkKPiAgIHsKPiAgIAlz dHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaiA9ICZya19vYmotPmJhc2U7Cj4gQEAgLTQ2LDMyICsx NzAsOTMgQEAgc3RhdGljIGludCByb2NrY2hpcF9nZW1fYWxsb2NfYnVmKHN0cnVjdCByb2NrY2hp cF9nZW1fb2JqZWN0ICpya19vYmosCj4gICAJcmV0dXJuIDA7Cj4gICB9Cj4gICAKPiAtc3RhdGlj IHZvaWQgcm9ja2NoaXBfZ2VtX2ZyZWVfYnVmKHN0cnVjdCByb2NrY2hpcF9nZW1fb2JqZWN0ICpy a19vYmopCj4gK3N0YXRpYyBpbnQgcm9ja2NoaXBfZ2VtX2FsbG9jX2J1ZihzdHJ1Y3Qgcm9ja2No aXBfZ2VtX29iamVjdCAqcmtfb2JqLAo+ICsJCQkJICBib29sIGFsbG9jX2ttYXApCj4gICB7Cj4g ICAJc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmogPSAmcmtfb2JqLT5iYXNlOwo+ICAgCXN0cnVj dCBkcm1fZGV2aWNlICpkcm0gPSBvYmotPmRldjsKPiArCXN0cnVjdCByb2NrY2hpcF9kcm1fcHJp dmF0ZSAqcHJpdmF0ZSA9IGRybS0+ZGV2X3ByaXZhdGU7Cj4gICAKPiAtCWRtYV9mcmVlX2F0dHJz KGRybS0+ZGV2LCBvYmotPnNpemUsIHJrX29iai0+a3ZhZGRyLCBya19vYmotPmRtYV9hZGRyLAo+ IC0JCSAgICAgICAmcmtfb2JqLT5kbWFfYXR0cnMpOwo+ICsJaWYgKHByaXZhdGUtPmRvbWFpbikK PiArCQlyZXR1cm4gcm9ja2NoaXBfZ2VtX2FsbG9jX2lvbW11KHJrX29iaiwgYWxsb2Nfa21hcCk7 Cj4gKwllbHNlCj4gKwkJcmV0dXJuIHJvY2tjaGlwX2dlbV9hbGxvY19kbWEocmtfb2JqLCBhbGxv Y19rbWFwKTsKPiAgIH0KPiAgIAo+IC1zdGF0aWMgaW50IHJvY2tjaGlwX2RybV9nZW1fb2JqZWN0 X21tYXAoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmosCj4gLQkJCQkJc3RydWN0IHZtX2FyZWFf c3RydWN0ICp2bWEpCj4gK3N0YXRpYyB2b2lkIHJvY2tjaGlwX2dlbV9mcmVlX2lvbW11KHN0cnVj dCByb2NrY2hpcF9nZW1fb2JqZWN0ICpya19vYmopCj4gK3sKPiArCXZ1bm1hcChya19vYmotPmt2 YWRkcik7Cj4gKwlyb2NrY2hpcF9nZW1faW9tbXVfdW5tYXAocmtfb2JqKTsKPiArCXJvY2tjaGlw X2dlbV9wdXRfcGFnZXMocmtfb2JqKTsKPiArfQo+ICAgCj4gK3N0YXRpYyB2b2lkIHJvY2tjaGlw X2dlbV9mcmVlX2RtYShzdHJ1Y3Qgcm9ja2NoaXBfZ2VtX29iamVjdCAqcmtfb2JqKQo+ICAgewo+ ICsJc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmogPSAmcmtfb2JqLT5iYXNlOwo+ICsJc3RydWN0 IGRybV9kZXZpY2UgKmRybSA9IG9iai0+ZGV2Owo+ICsKPiArCWRtYV9mcmVlX2F0dHJzKGRybS0+ ZGV2LCBvYmotPnNpemUsIHJrX29iai0+a3ZhZGRyLAo+ICsJCSAgICAgICBya19vYmotPmRtYV9h ZGRyLCAmcmtfb2JqLT5kbWFfYXR0cnMpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCByb2NrY2hp cF9nZW1fZnJlZV9idWYoc3RydWN0IHJvY2tjaGlwX2dlbV9vYmplY3QgKnJrX29iaikKPiArewo+ ICsJaWYgKHJrX29iai0+cGFnZXMpCj4gKwkJcm9ja2NoaXBfZ2VtX2ZyZWVfaW9tbXUocmtfb2Jq KTsKPiArCWVsc2UKPiArCQlyb2NrY2hpcF9nZW1fZnJlZV9kbWEocmtfb2JqKTsKPiArfQo+ICsK PiArc3RhdGljIGludCByb2NrY2hpcF9kcm1fZ2VtX29iamVjdF9tbWFwX2lvbW11KHN0cnVjdCBk cm1fZ2VtX29iamVjdCAqb2JqLAo+ICsJCQkJCSAgICAgIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAq dm1hKQo+ICt7Cj4gKwlzdHJ1Y3Qgcm9ja2NoaXBfZ2VtX29iamVjdCAqcmtfb2JqID0gdG9fcm9j a2NoaXBfb2JqKG9iaik7Cj4gKwl1bnNpZ25lZCBpbnQgaSwgY291bnQgPSBvYmotPnNpemUgPj4g UEFHRV9TSElGVDsKPiArCXVuc2lnbmVkIGxvbmcgdXNlcl9jb3VudCA9ICh2bWEtPnZtX2VuZCAt IHZtYS0+dm1fc3RhcnQpID4+IFBBR0VfU0hJRlQ7Cj4gKwl1bnNpZ25lZCBsb25nIHVhZGRyID0g dm1hLT52bV9zdGFydDsKPiAgIAlpbnQgcmV0Owo+ICsKPiArCWlmICh1c2VyX2NvdW50ID09IDAg fHwgdXNlcl9jb3VudCA+IGNvdW50KQo+ICsJCXJldHVybiAtRU5YSU87Cj4gKwo+ICsJZm9yIChp ID0gMDsgaSA8IHVzZXJfY291bnQ7IGkrKykgewo+ICsJCXJldCA9IHZtX2luc2VydF9wYWdlKHZt YSwgdWFkZHIsIHJrX29iai0+cGFnZXNbaV0pOwo+ICsJCWlmIChyZXQpCj4gKwkJCXJldHVybiBy ZXQ7Cj4gKwkJdWFkZHIgKz0gUEFHRV9TSVpFOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9 Cj4gKwo+ICtzdGF0aWMgaW50IHJvY2tjaGlwX2RybV9nZW1fb2JqZWN0X21tYXBfZG1hKHN0cnVj dCBkcm1fZ2VtX29iamVjdCAqb2JqLAo+ICsJCQkJCSAgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3Qg KnZtYSkKPiArewo+ICAgCXN0cnVjdCByb2NrY2hpcF9nZW1fb2JqZWN0ICpya19vYmogPSB0b19y b2NrY2hpcF9vYmoob2JqKTsKPiAgIAlzdHJ1Y3QgZHJtX2RldmljZSAqZHJtID0gb2JqLT5kZXY7 Cj4gICAKPiArCXJldHVybiBkbWFfbW1hcF9hdHRycyhkcm0tPmRldiwgdm1hLCBya19vYmotPmt2 YWRkciwgcmtfb2JqLT5kbWFfYWRkciwKPiArCQkJICAgICAgb2JqLT5zaXplLCAmcmtfb2JqLT5k bWFfYXR0cnMpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHJvY2tjaGlwX2RybV9nZW1fb2JqZWN0 X21tYXAoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmosCj4gKwkJCQkJc3RydWN0IHZtX2FyZWFf c3RydWN0ICp2bWEpCj4gK3sKPiArCWludCByZXQ7Cj4gKwlzdHJ1Y3Qgcm9ja2NoaXBfZ2VtX29i amVjdCAqcmtfb2JqID0gdG9fcm9ja2NoaXBfb2JqKG9iaik7Cj4gKwo+ICAgCS8qCj4gLQkgKiBk bWFfYWxsb2NfYXR0cnMoKSBhbGxvY2F0ZWQgYSBzdHJ1Y3QgcGFnZSB0YWJsZSBmb3Igcmtfb2Jq LCBzbyBjbGVhcgo+ICsJICogV2UgYWxsb2NhdGVkIGEgc3RydWN0IHBhZ2UgdGFibGUgZm9yIHJr X29iaiwgc28gY2xlYXIKPiAgIAkgKiBWTV9QRk5NQVAgZmxhZyB0aGF0IHdhcyBzZXQgYnkgZHJt X2dlbV9tbWFwX29iaigpL2RybV9nZW1fbW1hcCgpLgo+ICAgCSAqLwo+ICAgCXZtYS0+dm1fZmxh Z3MgJj0gflZNX1BGTk1BUDsKPiAgIAl2bWEtPnZtX3Bnb2ZmID0gMDsKPiAgIAo+IC0JcmV0ID0g ZG1hX21tYXBfYXR0cnMoZHJtLT5kZXYsIHZtYSwgcmtfb2JqLT5rdmFkZHIsIHJrX29iai0+ZG1h X2FkZHIsCj4gLQkJCSAgICAgb2JqLT5zaXplLCAmcmtfb2JqLT5kbWFfYXR0cnMpOwo+ICsJaWYg KHJrX29iai0+cGFnZXMpCj4gKwkJcmV0ID0gcm9ja2NoaXBfZHJtX2dlbV9vYmplY3RfbW1hcF9p b21tdShvYmosIHZtYSk7Cj4gKwllbHNlCj4gKwkJcmV0ID0gcm9ja2NoaXBfZHJtX2dlbV9vYmpl Y3RfbW1hcF9kbWEob2JqLCB2bWEpOwo+ICsKPiAgIAlpZiAocmV0KQo+ICAgCQlkcm1fZ2VtX3Zt X2Nsb3NlKHZtYSk7Cj4gICAKPiBAQCAtMTIxLDcgKzMwNiw3IEBAIHN0cnVjdCByb2NrY2hpcF9n ZW1fb2JqZWN0ICoKPiAgIAo+ICAgCW9iaiA9ICZya19vYmotPmJhc2U7Cj4gICAKPiAtCWRybV9n ZW1fcHJpdmF0ZV9vYmplY3RfaW5pdChkcm0sIG9iaiwgc2l6ZSk7Cj4gKwlkcm1fZ2VtX29iamVj dF9pbml0KGRybSwgb2JqLCBzaXplKTsKPiAgIAo+ICAgCXJldCA9IHJvY2tjaGlwX2dlbV9hbGxv Y19idWYocmtfb2JqLCBhbGxvY19rbWFwKTsKPiAgIAlpZiAocmV0KQo+IEBAIC0yNzcsNiArNDYy LDkgQEAgc3RydWN0IHNnX3RhYmxlICpyb2NrY2hpcF9nZW1fcHJpbWVfZ2V0X3NnX3RhYmxlKHN0 cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqKQo+ICAgCXN0cnVjdCBzZ190YWJsZSAqc2d0Owo+ICAg CWludCByZXQ7Cj4gICAKPiArCWlmIChya19vYmotPnBhZ2VzKQo+ICsJCXJldHVybiBkcm1fcHJp bWVfcGFnZXNfdG9fc2cocmtfb2JqLT5wYWdlcywgcmtfb2JqLT5udW1fcGFnZXMpOwo+ICsKPiAg IAlzZ3QgPSBremFsbG9jKHNpemVvZigqc2d0KSwgR0ZQX0tFUk5FTCk7Cj4gICAJaWYgKCFzZ3Qp Cj4gICAJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwo+IEBAIC0yOTcsNiArNDg1LDEwIEBAIHZv aWQgKnJvY2tjaGlwX2dlbV9wcmltZV92bWFwKHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqKQo+ ICAgewo+ICAgCXN0cnVjdCByb2NrY2hpcF9nZW1fb2JqZWN0ICpya19vYmogPSB0b19yb2NrY2hp cF9vYmoob2JqKTsKPiAgIAo+ICsJaWYgKHJrX29iai0+cGFnZXMpCj4gKwkJcmV0dXJuIHZtYXAo cmtfb2JqLT5wYWdlcywgcmtfb2JqLT5udW1fcGFnZXMsIFZNX01BUCwKPiArCQkJICAgIHBncHJv dF93cml0ZWNvbWJpbmUoUEFHRV9LRVJORUwpKTsKPiArCj4gICAJaWYgKGRtYV9nZXRfYXR0cihE TUFfQVRUUl9OT19LRVJORUxfTUFQUElORywgJnJrX29iai0+ZG1hX2F0dHJzKSkKPiAgIAkJcmV0 dXJuIE5VTEw7Cj4gICAKPiBAQCAtMzA1LDUgKzQ5NywxMiBAQCB2b2lkICpyb2NrY2hpcF9nZW1f cHJpbWVfdm1hcChzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaikKPiAgIAo+ICAgdm9pZCByb2Nr Y2hpcF9nZW1fcHJpbWVfdnVubWFwKHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqLCB2b2lkICp2 YWRkcikKPiAgIHsKPiAtCS8qIE5vdGhpbmcgdG8gZG8gKi8KPiArCXN0cnVjdCByb2NrY2hpcF9n ZW1fb2JqZWN0ICpya19vYmogPSB0b19yb2NrY2hpcF9vYmoob2JqKTsKPiArCj4gKwlpZiAocmtf b2JqLT5wYWdlcykgewo+ICsJCXZ1bm1hcCh2YWRkcik7Cj4gKwkJcmV0dXJuOwo+ICsJfQo+ICsK PiArCS8qIE5vdGhpbmcgdG8gZG8gaWYgYWxsb2NhdGVkIGJ5IERNQSBtYXBwaW5nIEFQSS4gKi8K PiAgIH0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL3JvY2tjaGlwX2Ry bV9nZW0uaCBiL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9yb2NrY2hpcF9kcm1fZ2VtLmgKPiBp bmRleCAzNTg0Yjk0Li42YWE2MWIyIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9yb2Nr Y2hpcC9yb2NrY2hpcF9kcm1fZ2VtLmgKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAv cm9ja2NoaXBfZHJtX2dlbS5oCj4gQEAgLTIzLDcgKzIzLDE2IEBAIHN0cnVjdCByb2NrY2hpcF9n ZW1fb2JqZWN0IHsKPiAgIAo+ICAgCXZvaWQgKmt2YWRkcjsKPiAgIAlkbWFfYWRkcl90IGRtYV9h ZGRyOwo+ICsKPiArCS8qIFVzZWQgd2hlbiBJT01NVSBpcyBkaXNhYmxlZCAqLwo+ICAgCXN0cnVj dCBkbWFfYXR0cnMgZG1hX2F0dHJzOwo+ICsKPiArCS8qIFVzZWQgd2hlbiBJT01NVSBpcyBlbmFi bGVkICovCj4gKwlzdHJ1Y3QgZHJtX21tX25vZGUgbW07Cj4gKwl1bnNpZ25lZCBsb25nIG51bV9w YWdlczsKPiArCXN0cnVjdCBwYWdlICoqcGFnZXM7Cj4gKwlzdHJ1Y3Qgc2dfdGFibGUgKnNndDsK PiArCXNpemVfdCBzaXplOwo+ICAgfTsKPiAgIAo+ICAgc3RydWN0IHNnX3RhYmxlICpyb2NrY2hp cF9nZW1fcHJpbWVfZ2V0X3NnX3RhYmxlKHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqKTsKCgot LSAK77ytYXJrIFlhbwoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9w Lm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1k ZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: mark.yao@rock-chips.com (Mark yao) Date: Fri, 8 Jul 2016 08:54:53 +0800 Subject: [PATCH v5 6/8] drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain In-Reply-To: <1466734413-7453-7-git-send-email-zhengsq@rock-chips.com> References: <1466734413-7453-1-git-send-email-zhengsq@rock-chips.com> <1466734413-7453-7-git-send-email-zhengsq@rock-chips.com> Message-ID: <577EF9DD.1010506@rock-chips.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On 2016?06?24? 10:13, Shunqian Zheng wrote: > From: Tomasz Figa > > The API is not suitable for subsystems consisting of multiple devices > and requires severe hacks to use it. To mitigate this, this patch > implements allocation and address space management locally by using > helpers provided by DRM framework, like other DRM drivers do, e.g. > Tegra. > > This patch should not introduce any functional changes until the driver > is made to attach subdevices into an IOMMU domain with the generic IOMMU > API, which will happen in following patch. Based heavily on GEM > implementation of Tegra DRM driver. Acked-by: Mark Yao > > Signed-off-by: Tomasz Figa > Signed-off-by: Shunqian Zheng > --- > drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 3 + > drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 221 ++++++++++++++++++++++++++-- > drivers/gpu/drm/rockchip/rockchip_drm_gem.h | 9 ++ > 3 files changed, 222 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h > index ea39329..5ab1223 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h > @@ -30,6 +30,7 @@ > > struct drm_device; > struct drm_connector; > +struct iommu_domain; > > /* > * Rockchip drm private crtc funcs. > @@ -61,6 +62,8 @@ struct rockchip_drm_private { > struct drm_gem_object *fbdev_bo; > const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC]; > struct drm_atomic_state *state; > + struct iommu_domain *domain; > + struct drm_mm mm; > }; > > int rockchip_register_crtc_funcs(struct drm_crtc *crtc, > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > index 394f92b..e7cd93d 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > @@ -19,11 +19,135 @@ > #include > > #include > +#include > > #include "rockchip_drm_drv.h" > #include "rockchip_drm_gem.h" > > -static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj, > +static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) > +{ > + struct drm_device *drm = rk_obj->base.dev; > + struct rockchip_drm_private *private = drm->dev_private; > + int prot = IOMMU_READ | IOMMU_WRITE; > + ssize_t ret; > + > + ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm, > + rk_obj->base.size, PAGE_SIZE, > + 0, 0, 0); > + if (ret < 0) { > + DRM_ERROR("out of I/O virtual memory: %zd\n", ret); > + return ret; > + } > + > + rk_obj->dma_addr = rk_obj->mm.start; > + > + ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl, > + rk_obj->sgt->nents, prot); > + if (ret < 0) { > + DRM_ERROR("failed to map buffer: %zd\n", ret); > + goto err_remove_node; > + } > + > + rk_obj->size = ret; > + > + return 0; > + > +err_remove_node: > + drm_mm_remove_node(&rk_obj->mm); > + > + return ret; > +} > + > +static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj) > +{ > + struct drm_device *drm = rk_obj->base.dev; > + struct rockchip_drm_private *private = drm->dev_private; > + > + iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size); > + drm_mm_remove_node(&rk_obj->mm); > + > + return 0; > +} > + > +static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj) > +{ > + struct drm_device *drm = rk_obj->base.dev; > + int ret, i; > + struct scatterlist *s; > + > + rk_obj->pages = drm_gem_get_pages(&rk_obj->base); > + if (IS_ERR(rk_obj->pages)) > + return PTR_ERR(rk_obj->pages); > + > + rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT; > + > + rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages); > + if (IS_ERR(rk_obj->sgt)) { > + ret = PTR_ERR(rk_obj->sgt); > + goto err_put_pages; > + } > + > + /* > + * Fake up the SG table so that dma_sync_sg_for_device() can be used > + * to flush the pages associated with it. > + * > + * TODO: Replace this by drm_clflush_sg() once it can be implemented > + * without relying on symbols that are not exported. > + */ > + for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i) > + sg_dma_address(s) = sg_phys(s); > + > + dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents, > + DMA_TO_DEVICE); > + > + return 0; > + > +err_put_pages: > + drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false); > + return ret; > +} > + > +static void rockchip_gem_put_pages(struct rockchip_gem_object *rk_obj) > +{ > + sg_free_table(rk_obj->sgt); > + kfree(rk_obj->sgt); > + drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false); > +} > + > +static int rockchip_gem_alloc_iommu(struct rockchip_gem_object *rk_obj, > + bool alloc_kmap) > +{ > + int ret; > + > + ret = rockchip_gem_get_pages(rk_obj); > + if (ret < 0) > + return ret; > + > + ret = rockchip_gem_iommu_map(rk_obj); > + if (ret < 0) > + goto err_free; > + > + if (alloc_kmap) { > + rk_obj->kvaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP, > + pgprot_writecombine(PAGE_KERNEL)); > + if (!rk_obj->kvaddr) { > + DRM_ERROR("failed to vmap() buffer\n"); > + ret = -ENOMEM; > + goto err_unmap; > + } > + } > + > + return 0; > + > +err_unmap: > + rockchip_gem_iommu_unmap(rk_obj); > +err_free: > + rockchip_gem_put_pages(rk_obj); > + > + return ret; > +} > + > +static int rockchip_gem_alloc_dma(struct rockchip_gem_object *rk_obj, > bool alloc_kmap) > { > struct drm_gem_object *obj = &rk_obj->base; > @@ -46,32 +170,93 @@ static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj, > return 0; > } > > -static void rockchip_gem_free_buf(struct rockchip_gem_object *rk_obj) > +static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj, > + bool alloc_kmap) > { > struct drm_gem_object *obj = &rk_obj->base; > struct drm_device *drm = obj->dev; > + struct rockchip_drm_private *private = drm->dev_private; > > - dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr, rk_obj->dma_addr, > - &rk_obj->dma_attrs); > + if (private->domain) > + return rockchip_gem_alloc_iommu(rk_obj, alloc_kmap); > + else > + return rockchip_gem_alloc_dma(rk_obj, alloc_kmap); > } > > -static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, > - struct vm_area_struct *vma) > +static void rockchip_gem_free_iommu(struct rockchip_gem_object *rk_obj) > +{ > + vunmap(rk_obj->kvaddr); > + rockchip_gem_iommu_unmap(rk_obj); > + rockchip_gem_put_pages(rk_obj); > +} > > +static void rockchip_gem_free_dma(struct rockchip_gem_object *rk_obj) > { > + struct drm_gem_object *obj = &rk_obj->base; > + struct drm_device *drm = obj->dev; > + > + dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr, > + rk_obj->dma_addr, &rk_obj->dma_attrs); > +} > + > +static void rockchip_gem_free_buf(struct rockchip_gem_object *rk_obj) > +{ > + if (rk_obj->pages) > + rockchip_gem_free_iommu(rk_obj); > + else > + rockchip_gem_free_dma(rk_obj); > +} > + > +static int rockchip_drm_gem_object_mmap_iommu(struct drm_gem_object *obj, > + struct vm_area_struct *vma) > +{ > + struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > + unsigned int i, count = obj->size >> PAGE_SHIFT; > + unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; > + unsigned long uaddr = vma->vm_start; > int ret; > + > + if (user_count == 0 || user_count > count) > + return -ENXIO; > + > + for (i = 0; i < user_count; i++) { > + ret = vm_insert_page(vma, uaddr, rk_obj->pages[i]); > + if (ret) > + return ret; > + uaddr += PAGE_SIZE; > + } > + > + return 0; > +} > + > +static int rockchip_drm_gem_object_mmap_dma(struct drm_gem_object *obj, > + struct vm_area_struct *vma) > +{ > struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > struct drm_device *drm = obj->dev; > > + return dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr, > + obj->size, &rk_obj->dma_attrs); > +} > + > +static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, > + struct vm_area_struct *vma) > +{ > + int ret; > + struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > + > /* > - * dma_alloc_attrs() allocated a struct page table for rk_obj, so clear > + * We allocated a struct page table for rk_obj, so clear > * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap(). > */ > vma->vm_flags &= ~VM_PFNMAP; > vma->vm_pgoff = 0; > > - ret = dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr, > - obj->size, &rk_obj->dma_attrs); > + if (rk_obj->pages) > + ret = rockchip_drm_gem_object_mmap_iommu(obj, vma); > + else > + ret = rockchip_drm_gem_object_mmap_dma(obj, vma); > + > if (ret) > drm_gem_vm_close(vma); > > @@ -121,7 +306,7 @@ struct rockchip_gem_object * > > obj = &rk_obj->base; > > - drm_gem_private_object_init(drm, obj, size); > + drm_gem_object_init(drm, obj, size); > > ret = rockchip_gem_alloc_buf(rk_obj, alloc_kmap); > if (ret) > @@ -277,6 +462,9 @@ struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj) > struct sg_table *sgt; > int ret; > > + if (rk_obj->pages) > + return drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages); > + > sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); > if (!sgt) > return ERR_PTR(-ENOMEM); > @@ -297,6 +485,10 @@ void *rockchip_gem_prime_vmap(struct drm_gem_object *obj) > { > struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > > + if (rk_obj->pages) > + return vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP, > + pgprot_writecombine(PAGE_KERNEL)); > + > if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, &rk_obj->dma_attrs)) > return NULL; > > @@ -305,5 +497,12 @@ void *rockchip_gem_prime_vmap(struct drm_gem_object *obj) > > void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) > { > - /* Nothing to do */ > + struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > + > + if (rk_obj->pages) { > + vunmap(vaddr); > + return; > + } > + > + /* Nothing to do if allocated by DMA mapping API. */ > } > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h > index 3584b94..6aa61b2 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h > @@ -23,7 +23,16 @@ struct rockchip_gem_object { > > void *kvaddr; > dma_addr_t dma_addr; > + > + /* Used when IOMMU is disabled */ > struct dma_attrs dma_attrs; > + > + /* Used when IOMMU is enabled */ > + struct drm_mm_node mm; > + unsigned long num_pages; > + struct page **pages; > + struct sg_table *sgt; > + size_t size; > }; > > struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj); -- ?ark Yao From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753771AbcGHAzL (ORCPT ); Thu, 7 Jul 2016 20:55:11 -0400 Received: from regular1.263xmail.com ([211.150.99.138]:38144 "EHLO regular1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753626AbcGHAzD (ORCPT ); Thu, 7 Jul 2016 20:55:03 -0400 X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 X-RL-SENDER: mark.yao@rock-chips.com X-FST-TO: tfiga@chromium.org X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: mark.yao@rock-chips.com X-UNIQUE-TAG: <26ae1ff76a9deb7a4d2edccfb72f4a3f> X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 Subject: Re: [PATCH v5 6/8] drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain To: Shunqian Zheng , joro@8bytes.org, heiko@sntech.de, robh+dt@kernel.org, mark.rutland@arm.com, linux@armlinux.org.uk, airlied@linux.ie, tfiga@google.com, xxm@rock-chips.com References: <1466734413-7453-1-git-send-email-zhengsq@rock-chips.com> <1466734413-7453-7-git-send-email-zhengsq@rock-chips.com> Cc: linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, devicetree@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, Tomasz Figa From: Mark yao Message-ID: <577EF9DD.1010506@rock-chips.com> Date: Fri, 8 Jul 2016 08:54:53 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <1466734413-7453-7-git-send-email-zhengsq@rock-chips.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2016年06月24日 10:13, Shunqian Zheng wrote: > From: Tomasz Figa > > The API is not suitable for subsystems consisting of multiple devices > and requires severe hacks to use it. To mitigate this, this patch > implements allocation and address space management locally by using > helpers provided by DRM framework, like other DRM drivers do, e.g. > Tegra. > > This patch should not introduce any functional changes until the driver > is made to attach subdevices into an IOMMU domain with the generic IOMMU > API, which will happen in following patch. Based heavily on GEM > implementation of Tegra DRM driver. Acked-by: Mark Yao > > Signed-off-by: Tomasz Figa > Signed-off-by: Shunqian Zheng > --- > drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 3 + > drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 221 ++++++++++++++++++++++++++-- > drivers/gpu/drm/rockchip/rockchip_drm_gem.h | 9 ++ > 3 files changed, 222 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h > index ea39329..5ab1223 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h > @@ -30,6 +30,7 @@ > > struct drm_device; > struct drm_connector; > +struct iommu_domain; > > /* > * Rockchip drm private crtc funcs. > @@ -61,6 +62,8 @@ struct rockchip_drm_private { > struct drm_gem_object *fbdev_bo; > const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC]; > struct drm_atomic_state *state; > + struct iommu_domain *domain; > + struct drm_mm mm; > }; > > int rockchip_register_crtc_funcs(struct drm_crtc *crtc, > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > index 394f92b..e7cd93d 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > @@ -19,11 +19,135 @@ > #include > > #include > +#include > > #include "rockchip_drm_drv.h" > #include "rockchip_drm_gem.h" > > -static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj, > +static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) > +{ > + struct drm_device *drm = rk_obj->base.dev; > + struct rockchip_drm_private *private = drm->dev_private; > + int prot = IOMMU_READ | IOMMU_WRITE; > + ssize_t ret; > + > + ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm, > + rk_obj->base.size, PAGE_SIZE, > + 0, 0, 0); > + if (ret < 0) { > + DRM_ERROR("out of I/O virtual memory: %zd\n", ret); > + return ret; > + } > + > + rk_obj->dma_addr = rk_obj->mm.start; > + > + ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl, > + rk_obj->sgt->nents, prot); > + if (ret < 0) { > + DRM_ERROR("failed to map buffer: %zd\n", ret); > + goto err_remove_node; > + } > + > + rk_obj->size = ret; > + > + return 0; > + > +err_remove_node: > + drm_mm_remove_node(&rk_obj->mm); > + > + return ret; > +} > + > +static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj) > +{ > + struct drm_device *drm = rk_obj->base.dev; > + struct rockchip_drm_private *private = drm->dev_private; > + > + iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size); > + drm_mm_remove_node(&rk_obj->mm); > + > + return 0; > +} > + > +static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj) > +{ > + struct drm_device *drm = rk_obj->base.dev; > + int ret, i; > + struct scatterlist *s; > + > + rk_obj->pages = drm_gem_get_pages(&rk_obj->base); > + if (IS_ERR(rk_obj->pages)) > + return PTR_ERR(rk_obj->pages); > + > + rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT; > + > + rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages); > + if (IS_ERR(rk_obj->sgt)) { > + ret = PTR_ERR(rk_obj->sgt); > + goto err_put_pages; > + } > + > + /* > + * Fake up the SG table so that dma_sync_sg_for_device() can be used > + * to flush the pages associated with it. > + * > + * TODO: Replace this by drm_clflush_sg() once it can be implemented > + * without relying on symbols that are not exported. > + */ > + for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i) > + sg_dma_address(s) = sg_phys(s); > + > + dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents, > + DMA_TO_DEVICE); > + > + return 0; > + > +err_put_pages: > + drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false); > + return ret; > +} > + > +static void rockchip_gem_put_pages(struct rockchip_gem_object *rk_obj) > +{ > + sg_free_table(rk_obj->sgt); > + kfree(rk_obj->sgt); > + drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false); > +} > + > +static int rockchip_gem_alloc_iommu(struct rockchip_gem_object *rk_obj, > + bool alloc_kmap) > +{ > + int ret; > + > + ret = rockchip_gem_get_pages(rk_obj); > + if (ret < 0) > + return ret; > + > + ret = rockchip_gem_iommu_map(rk_obj); > + if (ret < 0) > + goto err_free; > + > + if (alloc_kmap) { > + rk_obj->kvaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP, > + pgprot_writecombine(PAGE_KERNEL)); > + if (!rk_obj->kvaddr) { > + DRM_ERROR("failed to vmap() buffer\n"); > + ret = -ENOMEM; > + goto err_unmap; > + } > + } > + > + return 0; > + > +err_unmap: > + rockchip_gem_iommu_unmap(rk_obj); > +err_free: > + rockchip_gem_put_pages(rk_obj); > + > + return ret; > +} > + > +static int rockchip_gem_alloc_dma(struct rockchip_gem_object *rk_obj, > bool alloc_kmap) > { > struct drm_gem_object *obj = &rk_obj->base; > @@ -46,32 +170,93 @@ static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj, > return 0; > } > > -static void rockchip_gem_free_buf(struct rockchip_gem_object *rk_obj) > +static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj, > + bool alloc_kmap) > { > struct drm_gem_object *obj = &rk_obj->base; > struct drm_device *drm = obj->dev; > + struct rockchip_drm_private *private = drm->dev_private; > > - dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr, rk_obj->dma_addr, > - &rk_obj->dma_attrs); > + if (private->domain) > + return rockchip_gem_alloc_iommu(rk_obj, alloc_kmap); > + else > + return rockchip_gem_alloc_dma(rk_obj, alloc_kmap); > } > > -static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, > - struct vm_area_struct *vma) > +static void rockchip_gem_free_iommu(struct rockchip_gem_object *rk_obj) > +{ > + vunmap(rk_obj->kvaddr); > + rockchip_gem_iommu_unmap(rk_obj); > + rockchip_gem_put_pages(rk_obj); > +} > > +static void rockchip_gem_free_dma(struct rockchip_gem_object *rk_obj) > { > + struct drm_gem_object *obj = &rk_obj->base; > + struct drm_device *drm = obj->dev; > + > + dma_free_attrs(drm->dev, obj->size, rk_obj->kvaddr, > + rk_obj->dma_addr, &rk_obj->dma_attrs); > +} > + > +static void rockchip_gem_free_buf(struct rockchip_gem_object *rk_obj) > +{ > + if (rk_obj->pages) > + rockchip_gem_free_iommu(rk_obj); > + else > + rockchip_gem_free_dma(rk_obj); > +} > + > +static int rockchip_drm_gem_object_mmap_iommu(struct drm_gem_object *obj, > + struct vm_area_struct *vma) > +{ > + struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > + unsigned int i, count = obj->size >> PAGE_SHIFT; > + unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; > + unsigned long uaddr = vma->vm_start; > int ret; > + > + if (user_count == 0 || user_count > count) > + return -ENXIO; > + > + for (i = 0; i < user_count; i++) { > + ret = vm_insert_page(vma, uaddr, rk_obj->pages[i]); > + if (ret) > + return ret; > + uaddr += PAGE_SIZE; > + } > + > + return 0; > +} > + > +static int rockchip_drm_gem_object_mmap_dma(struct drm_gem_object *obj, > + struct vm_area_struct *vma) > +{ > struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > struct drm_device *drm = obj->dev; > > + return dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr, > + obj->size, &rk_obj->dma_attrs); > +} > + > +static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, > + struct vm_area_struct *vma) > +{ > + int ret; > + struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > + > /* > - * dma_alloc_attrs() allocated a struct page table for rk_obj, so clear > + * We allocated a struct page table for rk_obj, so clear > * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap(). > */ > vma->vm_flags &= ~VM_PFNMAP; > vma->vm_pgoff = 0; > > - ret = dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr, > - obj->size, &rk_obj->dma_attrs); > + if (rk_obj->pages) > + ret = rockchip_drm_gem_object_mmap_iommu(obj, vma); > + else > + ret = rockchip_drm_gem_object_mmap_dma(obj, vma); > + > if (ret) > drm_gem_vm_close(vma); > > @@ -121,7 +306,7 @@ struct rockchip_gem_object * > > obj = &rk_obj->base; > > - drm_gem_private_object_init(drm, obj, size); > + drm_gem_object_init(drm, obj, size); > > ret = rockchip_gem_alloc_buf(rk_obj, alloc_kmap); > if (ret) > @@ -277,6 +462,9 @@ struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj) > struct sg_table *sgt; > int ret; > > + if (rk_obj->pages) > + return drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages); > + > sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); > if (!sgt) > return ERR_PTR(-ENOMEM); > @@ -297,6 +485,10 @@ void *rockchip_gem_prime_vmap(struct drm_gem_object *obj) > { > struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > > + if (rk_obj->pages) > + return vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP, > + pgprot_writecombine(PAGE_KERNEL)); > + > if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, &rk_obj->dma_attrs)) > return NULL; > > @@ -305,5 +497,12 @@ void *rockchip_gem_prime_vmap(struct drm_gem_object *obj) > > void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) > { > - /* Nothing to do */ > + struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > + > + if (rk_obj->pages) { > + vunmap(vaddr); > + return; > + } > + > + /* Nothing to do if allocated by DMA mapping API. */ > } > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h > index 3584b94..6aa61b2 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h > @@ -23,7 +23,16 @@ struct rockchip_gem_object { > > void *kvaddr; > dma_addr_t dma_addr; > + > + /* Used when IOMMU is disabled */ > struct dma_attrs dma_attrs; > + > + /* Used when IOMMU is enabled */ > + struct drm_mm_node mm; > + unsigned long num_pages; > + struct page **pages; > + struct sg_table *sgt; > + size_t size; > }; > > struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj); -- Mark Yao