From mboxrd@z Thu Jan 1 00:00:00 1970 From: Boris Brezillon Subject: Re: [PATCH v1 7/7] drm: add Atmel LCDC display controller support Date: Fri, 24 Aug 2018 14:31:25 +0200 Message-ID: <20180824143125.4e99e791@bbrezillon> References: <20180812184152.GA22343@ravnborg.org> <20180812184629.3808-7-sam@ravnborg.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180812184629.3808-7-sam@ravnborg.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Sam Ravnborg Cc: Mark Rutland , devicetree@vger.kernel.org, Alexandre Belloni , linux-pwm@vger.kernel.org, Boris Brezillon , Nicolas Ferre , Nicolas Ferre , dri-devel@lists.freedesktop.org, Rob Herring , Lee Jones , linux-arm-kernel@lists.infradead.org List-Id: linux-pwm@vger.kernel.org K05vcmFsZgoKSGkgU2FtLAoKT24gU3VuLCAxMiBBdWcgMjAxOCAyMDo0NjoyOSArMDIwMApTYW0g UmF2bmJvcmcgPHNhbUByYXZuYm9yZy5vcmc+IHdyb3RlOgoKPiBUaGlzIGlzIGEgRFJNIGJhc2Vk IGRyaXZlciBmb3IgdGhlIEF0bWVsIExDREMgSVAuCj4gVGhlcmUgZXhpc3QgdG9kYXkgYSBmcmFt ZWJ1ZmZlciBiYXNlZCBkcml2ZXIgYW5kCj4gdGhpcyBpcyBhIHJlLWltcGxtZW50YXRpb24gb2Yg dGhlIHNhbWUgb24gdG9wIG9mIERSTS4KPiAKPiBUaGUgcmV3cml0ZSB3YXMgYmFzZWQgb24gdGhl IG9yaWdpbmFsIGZiZGV2IGRyaXZlcgo+IGJ1dCB0aGUgZHJpdmVyIGhhcyBhbHNvIHNlZW4gaW5z cGlyYXRpb24gZnJvbQo+IHRoZSBhdG1lbC1obGNkY19kYyBkcml2ZXIgYW5kIG90aGVycy4KPiAK PiBUaGUgZHJpdmVyIGlzIG5vdCBhIGZ1bGwgcmVwbGFjZW1lbnQ6Cj4gLSBTVE4gZGlzcGxheXMg YXJlIG5vdCBzdXBwb3J0ZWQKPiAJQmluZGluZyBzdXBwb3J0IGlzIG1pc3NpbmcgYnV0IG1vc3Qg b2YgdGhlCj4gCVNUTiBzcGVjaWZpYyBmdW5jdGlvbmFsaXR5IGlzIG90aGVyd2lzZSBwb3J0ZWQK PiAJZnJvbSB0aGUgZmJkZXYgZHJpdmVyLgo+IC0gZ2FtbWEgc3VwcG9ydCBpcyBtaXNzaW5nCj4g CVRoZSBkcml2ZXIgdXRpbGlzZXMgZHJtX3NpbXBsZV9rbXNfaGVscGVyIGFuZAo+IAl0aGlzIGhl bHBlciBsYWNrcyBzdXBwb3J0IGZvciBzZXR0dGluZyB1cCBnYW1tYQo+IC0gbW9kZXNldHRpbmcg aXMgbm90IGNoZWNrZWQgKHNlZSBUT0RPIGluIGZpbGUpCj4gLSBzdXBwb3J0IGZvciBleHRyYSBt b2RlcyBhcyBhcHBsaWNhYmxlIChhbmQgbGNkLXdpcmluZy1tb2RlKQo+IC0gc3VwcG9ydCBmb3Ig QVZSMzIgKGlzIGl0IHJlbGV2YW50PykKPiAKPiBTaWduZWQtb2ZmLWJ5OiBTYW0gUmF2bmJvcmcg PHNhbUByYXZuYm9yZy5vcmc+Cj4gQ2M6IE5pY29sYXMgRmVycmUgPG5pY29sYXMuZmVycmVAYXRt ZWwuY29tPgo+IENjOiBCb3JpcyBCcmV6aWxsb24gPGJvcmlzLmJyZXppbGxvbkBmcmVlLWVsZWN0 cm9ucy5jb20+Cj4gQ2M6IEFsZXhhbmRyZSBCZWxsb25pIDxhbGV4YW5kcmUuYmVsbG9uaUBib290 bGluLmNvbT4KPiAtLS0KPiAgTUFJTlRBSU5FUlMgICAgICAgICAgICAgICAgICAgICAgICAgICB8 ICAgIDcgKwo+ICBkcml2ZXJzL2dwdS9kcm0vYXRtZWwvS2NvbmZpZyAgICAgICAgIHwgICAxMiAr Cj4gIGRyaXZlcnMvZ3B1L2RybS9hdG1lbC9NYWtlZmlsZSAgICAgICAgfCAgICAyICsKPiAgZHJp dmVycy9ncHUvZHJtL2F0bWVsL2F0bWVsX2xjZGMtZGMuYyB8IDEwOTQgKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrCj4gIDQgZmlsZXMgY2hhbmdlZCwgMTExNSBpbnNlcnRpb25zKCsp Cj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vYXRtZWwvYXRtZWxfbGNkYy1k Yy5jCj4gCj4gZGlmZiAtLWdpdCBhL01BSU5UQUlORVJTIGIvTUFJTlRBSU5FUlMKPiBpbmRleCAw OWNlNzZhOWExZGMuLjBhNTk0ZDAyYTdjMCAxMDA2NDQKPiAtLS0gYS9NQUlOVEFJTkVSUwo+ICsr KyBiL01BSU5UQUlORVJTCj4gQEAgLTQ2ODUsNiArNDY4NSwxMyBAQCBGOglkcml2ZXJzL2dwdS9k cm0vYXRtZWwvYXRtZWwtaGxjZGMqCj4gIEY6CURvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5k aW5ncy9kaXNwbGF5L2F0bWVsLwo+ICBUOglnaXQgZ2l0Oi8vYW5vbmdpdC5mcmVlZGVza3RvcC5v cmcvZHJtL2RybS1taXNjCj4gIAo+ICtEUk0gRFJJVkVSUyBGT1IgQVRNRUwgTENEQwo+ICtNOglT YW0gUmF2bmJvcmcgPHNhbUByYXZuYm9yZy5vcmc+Cj4gK0w6CWRyaS1kZXZlbEBsaXN0cy5mcmVl ZGVza3RvcC5vcmcKPiArUzoJTWFpbnRhaW5lZAo+ICtGOglkcml2ZXJzL2dwdS9kcm0vYXRtZWwv YXRtZWwtbGNkYyoKPiArRjoJRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Rpc3Bs YXkvYXRtZWwvCj4gKwoKQXMgc3RhdGVkIGluIG9uZSBvZiBteSBwcmV2aW91cyByZXBsaWVzLCBJ IHRoaW5rIHdlIHNob3VsZCBrZWVwIGEKc2luZ2xlIGVudHJ5IGZvciBib3RoIGRyaXZlcnMsIGp1 c3QgdXBkYXRlIHRoZSBleGlzdGluZyBvbmUgYW5kIHdlCnNob3VsZCBiZSBnb29kLgoKPiAgRFJN IERSSVZFUlMgRk9SIEJSSURHRSBDSElQUwo+ICBNOglBcmNoaXQgVGFuZWphIDxhcmNoaXR0QGNv ZGVhdXJvcmEub3JnPgo+ICBNOglBbmRyemVqIEhhamRhIDxhLmhhamRhQHNhbXN1bmcuY29tPgoK Wy4uLl0KCj4gKy8qCj4gKyAqIFRoZSBBdG1lbCBMQ0QgY29udHJvbGxlciBkaXNwbGF5LWNvbnRy b2xsZXIgc3VwcG9ydHMgc2V2ZXJhbCBmb3JtYXRzIGJ1dAo+ICsgKiB0aGlzIGRyaXZlciBzdXBw b3J0cyBvbmx5IGEgc21hbGwgc3Vic2V0Lgo+ICsgKiBUT0RPOiBhdG1lbF9sY2RmYiBzdXBwb3J0 cyBtb3JlIC0gcG9ydCBpdCBvdmVyCj4gKyAqIE1heWJlIGFjdHVhbCB3aXJpbmcgd2lsbCBpbXBh Y3QgbW9kZSBzdXBwb3J0Pwo+ICsgKi8KPiArc3RhdGljIGNvbnN0IHUzMiBsY2RjX2RjX2Zvcm1h dHNbXSA9IHsKPiArCURSTV9GT1JNQVRfQkdSNTY1LAo+ICt9Owo+ICsKPiArLyogU3RhcnQgTENE IENvbnRyb2xsZXIgKERNQSArIFBXUikgKi8KPiArc3RhdGljIHZvaWQgbGNkY19kY19zdGFydChz dHJ1Y3QgbGNkY19kYyAqbGNkY19kYykKPiArewo+ICsJLy8gRW5hYmxlIERNQQoKQXZvaWQgdXNp bmcgQysrIHN0eWxlIGNvbW1lbnRzLgoKPiArCXJlZ21hcF93cml0ZShsY2RjX2RjLT5yZWdtYXAs IEFUTUVMX0xDRENfRE1BQ09OLCBBVE1FTF9MQ0RDX0RNQUVOKTsKPiArCS8vIEVuYWJsZSBMQ0QK PiArCXJlZ21hcF93cml0ZShsY2RjX2RjLT5yZWdtYXAsIEFUTUVMX0xDRENfUFdSQ09OLAo+ICsJ CSAgICAgKGxjZGNfZGMtPmRlc2MtPmd1YXJkX3RpbWUgPDwgQVRNRUxfTENEQ19HVUFSRFRfT0ZG U0VUKQo+ICsJCSAgICAgfCBBVE1FTF9MQ0RDX1BXUik7Cj4gK30KCj4gKwo+ICtzdGF0aWMgaW50 IGxjZGNfZGNfZGlzcGxheV9jaGVjayhzdHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBp cGUsCj4gKwkJCQkgc3RydWN0IGRybV9wbGFuZV9zdGF0ZSAqcHN0YXRlLAo+ICsJCQkJIHN0cnVj dCBkcm1fY3J0Y19zdGF0ZSAqY3N0YXRlKQo+ICt7Cj4gKwljb25zdCBzdHJ1Y3QgZHJtX2Rpc3Bs YXlfbW9kZSAqZG1vZGU7Cj4gKwlzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpvbGRfZmI7Cj4gKwlz dHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpmYjsKPiArCj4gKwlkbW9kZSA9ICZjc3RhdGUtPm1vZGU7 Cj4gKwlvbGRfZmIgPSBwaXBlLT5wbGFuZS5zdGF0ZS0+ZmI7Cj4gKwlmYiA9IHBzdGF0ZS0+ZmI7 Cj4gKwo+ICsJLyogQ2hlY2sgdGltaW5nPyAqLwoKRGlkIHlvdSBsb29rIGF0IHdoYXQgb3RoZXIg c2ltcGxlIERSTSBkcml2ZXJzIGNoZWNrIGluIHRoaXMgaG9vaz8KCj4gKwkvKiBUT0RPICovCj4g Kwo+ICsJcmV0dXJuIDA7Cj4gK30KCgo+ICsKPiArLyogc2NoZWR1bGVkIHdvcmtlciB0byByZXNl dCBMQ0QgKi8KPiArc3RhdGljIHZvaWQgcmVzZXRfbGNkY193b3JrKHN0cnVjdCB3b3JrX3N0cnVj dCAqd29yaykKPiArewo+ICsJc3RydWN0IGxjZGNfZGMgKmxjZGNfZGM7Cj4gKwo+ICsJbGNkY19k YyA9IGNvbnRhaW5lcl9vZih3b3JrLCBzdHJ1Y3QgbGNkY19kYywgcmVzZXRfbGNkY193b3JrKTsK PiArCgpIbSwgeW91IG5lZWQgYSBsb2NrIHRvIHByb3RlY3QgdGhpcyBzZWN0aW9uIGFuZCB5b3Ug aGF2ZSB0byBjaGVjayB0aGUKTENEQyBzdGF0ZSwgYmVjYXVzZSBpdCBtaWdodCBoYXZlIGJlZW4g ZGlzYWJsZWQgdGhyb3VnaCB0aGUgLT5kaXNhYmxlKCkKaG9vayBqdXN0IGFmdGVyIHlvdSBoYXZl IHNjaGVkdWxlZCB0aGlzIHJlc2V0IG9wZXJhdGlvbi4KCj4gKwlsY2RjX2RjX3N0b3AobGNkY19k Yyk7Cj4gKwlsY2RjX2RjX3N0YXJ0KGxjZGNfZGMpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaXJxcmV0 dXJuX3QgbGNkY19kY19pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICphcmcpCj4gK3sKPiArCXN0 cnVjdCBsY2RjX2RjICpsY2RjX2RjOwo+ICsJc3RydWN0IGRybV9kZXZpY2UgKmRybTsKPiArCXVu c2lnbmVkIGludCBzdGF0dXM7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gKwl1bnNpZ25lZCBp bnQgaW1yOwo+ICsJdW5zaWduZWQgaW50IGlzcjsKPiArCj4gKwlkcm0gPSBhcmc7Cj4gKwlsY2Rj X2RjID0gZHJtLT5kZXZfcHJpdmF0ZTsKPiArCWRldiA9IGxjZGNfZGMtPmRldjsKPiArCj4gKwly ZWdtYXBfcmVhZChsY2RjX2RjLT5yZWdtYXAsIEFUTUVMX0xDRENfSU1SLCAmaW1yKTsKPiArCXJl Z21hcF9yZWFkKGxjZGNfZGMtPnJlZ21hcCwgQVRNRUxfTENEQ19JU1IsICZpc3IpOwo+ICsJc3Rh dHVzID0gaW1yICYgaXNyOwo+ICsJaWYgKCFzdGF0dXMpCj4gKwkJcmV0dXJuIElSUV9OT05FOwo+ ICsKPiArCWlmIChzdGF0dXMgJiBBVE1FTF9MQ0RDX0xTVExOSSkKPiArCQlkcm1fY3J0Y19oYW5k bGVfdmJsYW5rKCZsY2RjX2RjLT5waXBlLmNydGMpOwo+ICsKPiArCWlmIChzdGF0dXMgJiBBVE1F TF9MQ0RDX1VGTFdJKSB7Cj4gKwkJRFJNX0RFVl9JTkZPKGRldiwgIkZJRk8gdW5kZXJmbG93ICUj eFxuIiwgc3RhdHVzKTsKPiArCQkvKiByZXNldCBETUEgYW5kIEZJRk8gdG8gYXZvaWQgc2NyZWVu IHNoaWZ0aW5nICovCj4gKwkJc2NoZWR1bGVfd29yaygmbGNkY19kYy0+cmVzZXRfbGNkY193b3Jr KTsKPiArCX0KCkFkZCBhIGJsYW5rIGxpbmUgaGVyZS4KCj4gKwlpZiAoc3RhdHVzICYgQVRNRUxf TENEQ19PV1JJKQo+ICsJCURSTV9ERVZfSU5GTyhkZXYsICJGSUZPIG92ZXJ3cml0ZSBpbnRlcnJ1 cHQiKTsKPiArCj4gKwlpZiAoc3RhdHVzICYgQVRNRUxfTENEQ19NRVJJKQo+ICsJCURSTV9ERVZf SU5GTyhkZXYsICJETUEgbWVtb3J5IGVycm9yIik7Cj4gKwo+ICsJLyogQ2xlYXIgYWxsIHJlcG9y dGVkIChmcm9tIElTUikgaW50ZXJydXB0cyAqLwo+ICsJcmVnbWFwX3dyaXRlKGxjZGNfZGMtPnJl Z21hcCwgQVRNRUxfTENEQ19JQ1IsIGlzcik7Cj4gKwo+ICsJcmV0dXJuIElSUV9IQU5ETEVEOwo+ ICt9Cj4gKwoKWy4uLl0KCj4gK3N0YXRpYyBpbnQgbGNkY19kY19tb2Rlc2V0X2luaXQoc3RydWN0 IGxjZGNfZGMgKmxjZGNfZGMsIHN0cnVjdCBkcm1fZGV2aWNlICpkcm0pCj4gK3sKPiArCXN0cnVj dCBkcm1fYnJpZGdlICpicmlkZ2U7Cj4gKwlzdHJ1Y3QgZHJtX3BhbmVsICpwYW5lbDsKPiArCXN0 cnVjdCBkZXZpY2Vfbm9kZSAqbnA7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gKwlpbnQgcmV0 Owo+ICsKPiArCWRldiA9IGRybS0+ZGV2Owo+ICsKPiArCWRybV9tb2RlX2NvbmZpZ19pbml0KGRy bSk7Cj4gKwlkcm0tPm1vZGVfY29uZmlnLm1pbl93aWR0aCAgPSBsY2RjX2RjLT5kZXNjLT5taW5f d2lkdGg7Cj4gKwlkcm0tPm1vZGVfY29uZmlnLm1pbl9oZWlnaHQgPSBsY2RjX2RjLT5kZXNjLT5t aW5faGVpZ2h0Owo+ICsJZHJtLT5tb2RlX2NvbmZpZy5tYXhfd2lkdGggID0gbGNkY19kYy0+ZGVz Yy0+bWF4X3dpZHRoOwo+ICsJZHJtLT5tb2RlX2NvbmZpZy5tYXhfaGVpZ2h0ID0gbGNkY19kYy0+ ZGVzYy0+bWF4X2hlaWdodDsKPiArCWRybS0+bW9kZV9jb25maWcuZnVuY3MJICAgID0gJm1vZGVf Y29uZmlnX2Z1bmNzOwo+ICsKPiArCW5wID0gZGV2LT5vZl9ub2RlOwo+ICsJLyogcG9ydEAwIGlz IHRoZSBvdXRwdXQgcG9ydCAqLwo+ICsJcmV0ID0gZHJtX29mX2ZpbmRfcGFuZWxfb3JfYnJpZGdl KG5wLCAwLCAwLCAmcGFuZWwsICZicmlkZ2UpOwo+ICsJaWYgKHJldCAmJiByZXQgIT0gLUVOT0RF Vikgewo+ICsJCURSTV9ERVZfRVJST1IoZGV2LCAiRmFpbGVkIHRvIGZpbmQgcGFuZWwgKCVkKVxu IiwgcmV0KTsKPiArCQlnb3RvIGVycl9vdXQ7CgoJCXJldHVybiByZXQ7Cgo+ICsJfQo+ICsKPiAr CWJyaWRnZSA9IGRybV9wYW5lbF9icmlkZ2VfYWRkKHBhbmVsLCBEUk1fTU9ERV9DT05ORUNUT1Jf VW5rbm93bik7Cgpkcm1fb2ZfZmluZF9wYW5lbF9vcl9icmlkZ2UoKSBtaWdodCBkaXJlY3RseSBy ZXR1cm4gYSBicmlkZ2UuIEFuZCBtYXliZQp3ZSBzaG91bGQgZGVjbGFyZSBhIERQSSBjb25uZWN0 b3IuIEFuZCBmaW5hbGx5LCB5b3UgY2FuIG1pZ2h0IHdhbnQgdG8KdXNlIGRldm1fZHJtX3BhbmVs X2JyaWRnZV9hZGQoKSBpbnN0ZWFkIG9mIGRybV9wYW5lbF9icmlkZ2VfYWRkKCkKCglpZiAocGFu ZWwpCgkJYnJpZGdlID0gZGV2bV9kcm1fcGFuZWxfYnJpZGdlX2FkZChkZXYsIHBhbmVsLAoJCQkJ CQkgICBEUk1fTU9ERV9DT05ORUNUT1JfRFBJKTsKCgo+ICsJaWYgKElTX0VSUihicmlkZ2UpKSB7 Cj4gKwkJcmV0ID0gUFRSX0VSUihicmlkZ2UpOwo+ICsJCURSTV9ERVZfRVJST1IoZGV2LCAiRmFp bGVkIHRvIGFkZCBicmlkZ2UgKCVkKSIsIHJldCk7Cj4gKwkJZ290byBlcnJfcGFuZWxfcmVtb3Zl OwoKSG0sIGlmIGRybV9wYW5lbF9icmlkZ2VfYWRkKCkgZmFpbGVkLCB5b3Ugc2hvdWxkbid0IGNh bGwKZHJtX3BhbmVsX2JyaWRnZV9yZW1vdmUoYnJpZGdlKS4gWW91IGNhbiBqdXN0IGRvCgoJCXJl dHVybiByZXQ7Cgo+ICsJfQo+ICsKPiArCWxjZGNfZGMtPnBhbmVsID0gcGFuZWw7Cj4gKwlsY2Rj X2RjLT5icmlkZ2UgPSBicmlkZ2U7Cj4gKwo+ICsJcmV0ID0gZHJtX3NpbXBsZV9kaXNwbGF5X3Bp cGVfaW5pdChkcm0sCj4gKwkJCQkJICAgJmxjZGNfZGMtPnBpcGUsCj4gKwkJCQkJICAgJmxjZGNf ZGNfZGlzcGxheV9mdW5jcywKPiArCQkJCQkgICBsY2RjX2RjX2Zvcm1hdHMsCj4gKwkJCQkJICAg QVJSQVlfU0laRShsY2RjX2RjX2Zvcm1hdHMpLAo+ICsJCQkJCSAgIE5VTEwsCj4gKwkJCQkJICAg JmxjZGNfZGMtPmNvbm5lY3Rvcik7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJRFJNX0RFVl9FUlJPUihk ZXYsICJGYWlsZWQgdG8gaW5pdCBkaXNwbGF5IHBpcGUgKCVkKVxuIiwgcmV0KTsKPiArCQlnb3Rv IGVycl9wYW5lbF9yZW1vdmU7CgpJZiB5b3UgdXNlIGRldm1fZHJtX3BhbmVsX2JyaWRnZV9hZGQo KSwgeW91IGNhbiByZXR1cm4gZGlyZWN0bHkuCgo+ICsJfQo+ICsKPiArCXJldCA9IGRybV9zaW1w bGVfZGlzcGxheV9waXBlX2F0dGFjaF9icmlkZ2UoJmxjZGNfZGMtPnBpcGUsIGJyaWRnZSk7Cj4g KwlpZiAocmV0KSB7Cj4gKwkJRFJNX0RFVl9FUlJPUihkZXYsICJmYWlsZWQgdG8gYXR0YWNoIGJy aWRnZSAoJWQpIiwgcmV0KTsKPiArCQlnb3RvIGVycl9wYW5lbF9yZW1vdmU7CgpEaXR0by4KCj4g Kwl9Cj4gKwo+ICsJZHJtX21vZGVfY29uZmlnX3Jlc2V0KGRybSk7Cj4gKwo+ICsJcmV0dXJuIDA7 Cj4gKwo+ICtlcnJfcGFuZWxfcmVtb3ZlOgo+ICsJaWYgKHBhbmVsKQo+ICsJCWRybV9wYW5lbF9i cmlkZ2VfcmVtb3ZlKGJyaWRnZSk7Cj4gKwo+ICtlcnJfb3V0Ogo+ICsJcmV0dXJuIHJldDsKCkFu ZCBub3cgeW91IHNob3VsZCBiZSBhYmxlIHRvIGdldCByaWQgb2YgdGhlIGVycm9yIHBhdGggZW50 aXJlbHkuCgo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGxjZGNfZGNfbG9hZChzdHJ1Y3QgZHJtX2Rl dmljZSAqZHJtKQo+ICt7Cj4gKwljb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkICptYXRjaDsKPiAr CXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXY7Cj4gKwlzdHJ1Y3QgbGNkY19kYyAqbGNkY19k YzsKPiArCXN0cnVjdCBkZXZpY2UgKmRldjsKPiArCWludCByZXQ7Cj4gKwo+ICsJZGV2ID0gZHJt LT5kZXY7Cj4gKwlwZGV2ID0gdG9fcGxhdGZvcm1fZGV2aWNlKGRldik7Cj4gKwo+ICsJbWF0Y2gg PSBvZl9tYXRjaF9ub2RlKGF0bWVsX2xjZGNfb2ZfbWF0Y2gsIGRldi0+cGFyZW50LT5vZl9ub2Rl KTsKPiArCWlmICghbWF0Y2gpIHsKPiArCQlEUk1fREVWX0VSUk9SKGRldiwgImludmFsaWQgY29t cGF0aWJsZSBzdHJpbmcgKG5vZGU9JXMpIiwKPiArCQkJICAgICAgZGV2LT5wYXJlbnQtPm9mX25v ZGUtPm5hbWUpOwo+ICsJCXJldHVybiAtRU5PREVWOwo+ICsJfQo+ICsKPiArCWlmICghbWF0Y2gt PmRhdGEpIHsKPiArCQlEUk1fREVWX0VSUk9SKGRldiwgImludmFsaWQgbGNkY19kYyBkZXNjcmlw dGlvblxuIik7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJbGNkY19kYyA9IGRl dm1fa3phbGxvYyhkZXYsIHNpemVvZigqbGNkY19kYyksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFs Y2RjX2RjKSB7Cj4gKwkJRFJNX0RFVl9FUlJPUihkZXYsICJGYWlsZWQgdG8gYWxsb2NhdGUgbGNk Y19kY1xuIik7Cj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwl9Cj4gKwo+ICsJLyogcmVzZXQgb2Yg bGNkYyBtaWdodCBzbGVlcCBhbmQgcmVxdWlyZSBhIHByZWVtcHRpYmxlIHRhc2sgY29udGV4dCAq Lwo+ICsJSU5JVF9XT1JLKCZsY2RjX2RjLT5yZXNldF9sY2RjX3dvcmssIHJlc2V0X2xjZGNfd29y ayk7Cj4gKwo+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwgZHJtKTsKPiArCWRldl9zZXRf ZHJ2ZGF0YShkZXYsIGxjZGNfZGMpOwo+ICsKPiArCWxjZGNfZGMtPm1mZF9sY2RjID0gZGV2X2dl dF9kcnZkYXRhKGRldi0+cGFyZW50KTsKPiArCWRybS0+ZGV2X3ByaXZhdGUgPSBsY2RjX2RjOwo+ ICsKPiArCWxjZGNfZGMtPnJlZ21hcCA9IGxjZGNfZGMtPm1mZF9sY2RjLT5yZWdtYXA7Cj4gKwls Y2RjX2RjLT5kZXNjID0gbWF0Y2gtPmRhdGE7Cj4gKwlsY2RjX2RjLT5kZXYgPSBkZXY7Cj4gKwo+ ICsJbGNkY19kYy0+bGNkX3N1cHBseSA9IGRldm1fcmVndWxhdG9yX2dldChkZXYsICJsY2QiKTsK PiArCWlmIChJU19FUlIobGNkY19kYy0+bGNkX3N1cHBseSkpIHsKPiArCQlEUk1fREVWX0VSUk9S KGRldiwgIkZhaWxlZCB0byBnZXQgbGNkLXN1cHBseSAoJWxkKVxuIiwKPiArCQkJICAgICAgUFRS X0VSUihsY2RjX2RjLT5sY2Rfc3VwcGx5KSk7Cj4gKwkJbGNkY19kYy0+bGNkX3N1cHBseSA9IE5V TEw7Cj4gKwl9Cj4gKwo+ICsJbGNkY19kY19zdGFydF9jbG9jayhsY2RjX2RjKTsKCkhtLCBkbyB5 b3UgcmVhbGx5IG5lZWQgdG8gY2FsbCB0aGF0IGhlcmU/IEknZCBtYWtlIGl0IHBhcnQgb2YgdGhl CnJ1bnRpbWUgUE0gcmVzdW1lIGhvb2ssIGFuZCBwdXQgYSBsY2RjX2RjX3N0b3BfY2xvY2soKSBp biB0aGUgc3VzcGVuZApob29rLgoKPiArCj4gKwlwbV9ydW50aW1lX2VuYWJsZShkZXYpOwo+ICsK PiArCXJldCA9IGRybV92YmxhbmtfaW5pdChkcm0sIDEpOwo+ICsJaWYgKHJldCkgewo+ICsJCURS TV9ERVZfRVJST1IoZGV2LCAiZmFpbGVkIHRvIGluaXRpYWxpemUgdmJsYW5rICglZClcbiIsCj4g KwkJCSAgICAgIHJldCk7Cj4gKwkJZ290byBlcnJfcG1fcnVudGltZV9kaXNhYmxlOwo+ICsJfQo+ ICsKPiArCXJldCA9IGxjZGNfZGNfbW9kZXNldF9pbml0KGxjZGNfZGMsIGRybSk7Cj4gKwlpZiAo cmV0KSB7Cj4gKwkJRFJNX0RFVl9FUlJPUihkZXYsICJtb2Rlc2V0X2luaXQgZmFpbGVkICglZCki LCByZXQpOwo+ICsJCWdvdG8gZXJyX3BtX3J1bnRpbWVfZGlzYWJsZTsKPiArCX0KPiArCj4gKwlw bV9ydW50aW1lX2dldF9zeW5jKGRldik7CgpUaGlzIGNhbGwgd2lsbCBhdXRvbWF0aWNhbGx5IGNh bGwgdGhlIHJ1bnRpbWUgUE0gcmVzdW1lIGhvb2ssIHNvIGlmIHlvdQpuZWVkIHRoZSBjbGsgdG8g YmUgZW5hYmxlZCBiZWZvcmUgdGhhdCBwb2ludCB5b3Ugc2hvdWxkIHB1dCBpdCBlYXJsaWVyLgoK QWxzbywgeW91IHNob3VsZCBjYWxsIHBtX3J1bnRpbWVfZ2V0X3N5bmMoKSBpbiB0aGUgLT5lbmFi bGUoKSBwYXRoIGFuZApwbV9ydW50aW1lX3B1dCgpIGluIHRoZSAtPmRpc2FibGUoKSBwYXRoLgoK PiArCXJldCA9IGRybV9pcnFfaW5zdGFsbChkcm0sIGxjZGNfZGMtPm1mZF9sY2RjLT5pcnEpOwo+ ICsJcG1fcnVudGltZV9wdXRfc3luYyhkZXYpOwo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlEUk1f REVWX0VSUk9SKGRldiwgIkZhaWxlZCB0byBpbnN0YWxsIElSUSAoJWQpXG4iLCByZXQpOwo+ICsK PiArCQlnb3RvIGVycl9wbV9ydW50aW1lX2Rpc2FibGU7Cj4gKwl9Cj4gKwo+ICsJLyoKPiArCSAq IFBhc3NpbmcgaW4gMTYgaGVyZSB3aWxsIG1ha2UgdGhlIFJHQjY1NiBtb2RlIHRoZSBkZWZhdWx0 Cj4gKwkgKiBQYXNzaW5nIGluIDMyIHdpbGwgdXNlIFhSR0I4ODg4IG1vZGUKPiArCSAqLwo+ICsJ ZHJtX2ZiX2NtYV9mYmRldl9pbml0KGRybSwgMTYsIDApOwo+ICsKPiArCWRybV9rbXNfaGVscGVy X3BvbGxfaW5pdChkcm0pOwo+ICsKPiArCWxjZGNfZGMtPmZiZGV2ID0gZHJtX2ZiZGV2X2NtYV9p bml0KGRybSwgOCwgMSk7Cj4gKwlpZiAoSVNfRVJSKGxjZGNfZGMtPmZiZGV2KSkgewo+ICsJCXJl dCA9IFBUUl9FUlIobGNkY19kYy0+ZmJkZXYpOwo+ICsJCURSTV9ERVZfRVJST1IoZGV2LCAiRmFp bGVkIHRvIGluaXQgRkIgQ01BIGFyZWEgKCVkKSIsIHJldCk7Cj4gKwkJZ290byBlcnJfaXJxX3Vu aW5zdGFsbDsKPiArCX0KPiArCj4gKwlkcm1faGVscGVyX2hwZF9pcnFfZXZlbnQoZHJtKTsKPiAr Cj4gKwlyZXR1cm4gMDsKPiArCj4gK2Vycl9pcnFfdW5pbnN0YWxsOgo+ICsJcG1fcnVudGltZV9n ZXRfc3luYyhkZXYpOwo+ICsJZHJtX2lycV91bmluc3RhbGwoZHJtKTsKPiArCXBtX3J1bnRpbWVf cHV0X3N5bmMoZGV2KTsKPiArCj4gK2Vycl9wbV9ydW50aW1lX2Rpc2FibGU6Cj4gKwlwbV9ydW50 aW1lX2Rpc2FibGUoZGV2KTsKPiArCWxjZGNfZGNfc3RvcF9jbG9jayhsY2RjX2RjKTsKPiArCj4g KwljYW5jZWxfd29ya19zeW5jKCZsY2RjX2RjLT5yZXNldF9sY2RjX3dvcmspOwoKSXNuJ3QgdGhl cmUgYSByYWNlIGhlcmU/IFdoYXQgaWYgdGhlcmUgd2FzIGEgd29yayBxdWV1ZWQgYnV0IHlvdQpk aXNhYmxlZCB0aGUgY2xrPyBJIGd1ZXNzIHJlZyByZWFkL3dyaXRlIGFjY2Vzc2VzIG1pZ2h0IGZh aWwgKGRvbid0Cmtub3cgaG93IGJhZCB0aGlzIGNhbiBnbyB0aG91Z2gpLgoKPiArCj4gKwlyZXR1 cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBsY2RjX2RjX3VubG9hZChzdHJ1Y3QgZHJt X2RldmljZSAqZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgbGNkY19kYyAqbGNkY19kYyA9IGRldi0+ZGV2 X3ByaXZhdGU7Cj4gKwo+ICsJZHJtX2ZiX2NtYV9mYmRldl9maW5pKGRldik7Cj4gKwlmbHVzaF93 b3JrKCZsY2RjX2RjLT5yZXNldF9sY2RjX3dvcmspOwo+ICsJZHJtX2ttc19oZWxwZXJfcG9sbF9m aW5pKGRldik7Cj4gKwlpZiAobGNkY19kYy0+cGFuZWwpCj4gKwkJZHJtX3BhbmVsX2JyaWRnZV9y ZW1vdmUobGNkY19kYy0+YnJpZGdlKTsKCllvdSBjYW4gZHJvcCB0aGF0IG9uZSBpZiB5b3UgdXNl IHRoZSBkZXZtXyB2ZXJzaW9uLgoKPiArCWRybV9tb2RlX2NvbmZpZ19jbGVhbnVwKGRldik7Cj4g Kwo+ICsJcG1fcnVudGltZV9nZXRfc3luYyhkZXYtPmRldik7Cj4gKwlkcm1faXJxX3VuaW5zdGFs bChkZXYpOwo+ICsJcG1fcnVudGltZV9wdXRfc3luYyhkZXYtPmRldik7Cj4gKwo+ICsJZGV2LT5k ZXZfcHJpdmF0ZSA9IE5VTEw7Cj4gKwo+ICsJcG1fcnVudGltZV9kaXNhYmxlKGRldi0+ZGV2KTsK PiArCWxjZGNfZGNfc3RvcF9jbG9jayhsY2RjX2RjKTsKPiArCWNhbmNlbF93b3JrX3N5bmMoJmxj ZGNfZGMtPnJlc2V0X2xjZGNfd29yayk7CgpBbmQgYWdhaW4sIGl0IG1pZ2h0IGJlIHRvbyBsYXRl LiBTaG91bGQgYmUgbW92ZWQganVzdCBhZnRlciBkaXNhYmxpbmcKdGhlIElSUSwgc2luY2UgdGhp cyBpcyB0aGUgb25seSBwYXRoIHdoZXJlIHlvdSBxdWV1ZSB0aGlzIHdvcmsuCgo+ICt9Cj4gKwo+ ICsKPiArc3RhdGljIGludCBsY2RjX2RjX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk ZXYpCj4gK3sKPiArCXN0cnVjdCBkcm1fZGV2aWNlICpkcm07Cj4gKwlzdHJ1Y3QgZGV2aWNlICpk ZXY7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWRldiA9ICZwZGV2LT5kZXY7Cj4gKwo+ICsJZHJtID0g ZHJtX2Rldl9hbGxvYygmbGNkY19kY19kcm1fZHJpdmVyLCBkZXYpOwo+ICsJaWYgKElTX0VSUihk cm0pKSB7Cj4gKwkJRFJNX0RFVl9FUlJPUihkZXYsICJGYWlsZWQgdG8gYWxsb2NhdGUgZHJtIGRl dmljZVxuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIoZHJtKTsKPiArCX0KPiArCj4gKwlyZXQgPSBs Y2RjX2RjX2xvYWQoZHJtKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBlcnJfcHV0X3JlZjsKPiAr Cj4gKwlyZXQgPSBkcm1fZGV2X3JlZ2lzdGVyKGRybSwgMCk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJ RFJNX0RFVl9FUlJPUihkZXYsICJGYWlsZWQgdG8gcmVnaXN0ZXIgZHJtICglZClcbiIsIHJldCk7 Cj4gKwkJZ290byBlcnJfdW5sb2FkOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArZXJy X3VubG9hZDoKPiArCWxjZGNfZGNfdW5sb2FkKGRybSk7Cj4gKwo+ICtlcnJfcHV0X3JlZjoKPiAr CWRybV9kZXZfcHV0KGRybSk7Cj4gKwlyZXR1cm4gcmV0Owo+ICt9CgpUaGF0J3MgYWxsIEkgc2Vl IGZvciBub3csIGJ1dCBrZWVwIGluIG1pbmQgdGhhdCBJIGRvbid0IGtub3cgbXVjaCBhYm91dAp0 aGUgRFJNIHNpbXBsZSBpbnRlcmZhY2UsIHNvIHlvdSdkIGJldHRlciB3YWl0IGZvciBhIHJldmll dyBmcm9tCnNvbWVvbmUgd2hvIGtub3dzIGJldHRlciAoTm9yYWxmPykuCgpSZWdhcmRzLAoKQm9y aXMKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRl dmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8v bGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: boris.brezillon@bootlin.com (Boris Brezillon) Date: Fri, 24 Aug 2018 14:31:25 +0200 Subject: [PATCH v1 7/7] drm: add Atmel LCDC display controller support In-Reply-To: <20180812184629.3808-7-sam@ravnborg.org> References: <20180812184152.GA22343@ravnborg.org> <20180812184629.3808-7-sam@ravnborg.org> Message-ID: <20180824143125.4e99e791@bbrezillon> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org +Noralf Hi Sam, On Sun, 12 Aug 2018 20:46:29 +0200 Sam Ravnborg wrote: > This is a DRM based driver for the Atmel LCDC IP. > There exist today a framebuffer based driver and > this is a re-implmentation of the same on top of DRM. > > The rewrite was based on the original fbdev driver > but the driver has also seen inspiration from > the atmel-hlcdc_dc driver and others. > > The driver is not a full replacement: > - STN displays are not supported > Binding support is missing but most of the > STN specific functionality is otherwise ported > from the fbdev driver. > - gamma support is missing > The driver utilises drm_simple_kms_helper and > this helper lacks support for settting up gamma > - modesetting is not checked (see TODO in file) > - support for extra modes as applicable (and lcd-wiring-mode) > - support for AVR32 (is it relevant?) > > Signed-off-by: Sam Ravnborg > Cc: Nicolas Ferre > Cc: Boris Brezillon > Cc: Alexandre Belloni > --- > MAINTAINERS | 7 + > drivers/gpu/drm/atmel/Kconfig | 12 + > drivers/gpu/drm/atmel/Makefile | 2 + > drivers/gpu/drm/atmel/atmel_lcdc-dc.c | 1094 +++++++++++++++++++++++++++++++++ > 4 files changed, 1115 insertions(+) > create mode 100644 drivers/gpu/drm/atmel/atmel_lcdc-dc.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 09ce76a9a1dc..0a594d02a7c0 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -4685,6 +4685,13 @@ F: drivers/gpu/drm/atmel/atmel-hlcdc* > F: Documentation/devicetree/bindings/display/atmel/ > T: git git://anongit.freedesktop.org/drm/drm-misc > > +DRM DRIVERS FOR ATMEL LCDC > +M: Sam Ravnborg > +L: dri-devel at lists.freedesktop.org > +S: Maintained > +F: drivers/gpu/drm/atmel/atmel-lcdc* > +F: Documentation/devicetree/bindings/display/atmel/ > + As stated in one of my previous replies, I think we should keep a single entry for both drivers, just update the existing one and we should be good. > DRM DRIVERS FOR BRIDGE CHIPS > M: Archit Taneja > M: Andrzej Hajda [...] > +/* > + * The Atmel LCD controller display-controller supports several formats but > + * this driver supports only a small subset. > + * TODO: atmel_lcdfb supports more - port it over > + * Maybe actual wiring will impact mode support? > + */ > +static const u32 lcdc_dc_formats[] = { > + DRM_FORMAT_BGR565, > +}; > + > +/* Start LCD Controller (DMA + PWR) */ > +static void lcdc_dc_start(struct lcdc_dc *lcdc_dc) > +{ > + // Enable DMA Avoid using C++ style comments. > + regmap_write(lcdc_dc->regmap, ATMEL_LCDC_DMACON, ATMEL_LCDC_DMAEN); > + // Enable LCD > + regmap_write(lcdc_dc->regmap, ATMEL_LCDC_PWRCON, > + (lcdc_dc->desc->guard_time << ATMEL_LCDC_GUARDT_OFFSET) > + | ATMEL_LCDC_PWR); > +} > + > +static int lcdc_dc_display_check(struct drm_simple_display_pipe *pipe, > + struct drm_plane_state *pstate, > + struct drm_crtc_state *cstate) > +{ > + const struct drm_display_mode *dmode; > + struct drm_framebuffer *old_fb; > + struct drm_framebuffer *fb; > + > + dmode = &cstate->mode; > + old_fb = pipe->plane.state->fb; > + fb = pstate->fb; > + > + /* Check timing? */ Did you look at what other simple DRM drivers check in this hook? > + /* TODO */ > + > + return 0; > +} > + > +/* scheduled worker to reset LCD */ > +static void reset_lcdc_work(struct work_struct *work) > +{ > + struct lcdc_dc *lcdc_dc; > + > + lcdc_dc = container_of(work, struct lcdc_dc, reset_lcdc_work); > + Hm, you need a lock to protect this section and you have to check the LCDC state, because it might have been disabled through the ->disable() hook just after you have scheduled this reset operation. > + lcdc_dc_stop(lcdc_dc); > + lcdc_dc_start(lcdc_dc); > +} > + > +static irqreturn_t lcdc_dc_irq_handler(int irq, void *arg) > +{ > + struct lcdc_dc *lcdc_dc; > + struct drm_device *drm; > + unsigned int status; > + struct device *dev; > + unsigned int imr; > + unsigned int isr; > + > + drm = arg; > + lcdc_dc = drm->dev_private; > + dev = lcdc_dc->dev; > + > + regmap_read(lcdc_dc->regmap, ATMEL_LCDC_IMR, &imr); > + regmap_read(lcdc_dc->regmap, ATMEL_LCDC_ISR, &isr); > + status = imr & isr; > + if (!status) > + return IRQ_NONE; > + > + if (status & ATMEL_LCDC_LSTLNI) > + drm_crtc_handle_vblank(&lcdc_dc->pipe.crtc); > + > + if (status & ATMEL_LCDC_UFLWI) { > + DRM_DEV_INFO(dev, "FIFO underflow %#x\n", status); > + /* reset DMA and FIFO to avoid screen shifting */ > + schedule_work(&lcdc_dc->reset_lcdc_work); > + } Add a blank line here. > + if (status & ATMEL_LCDC_OWRI) > + DRM_DEV_INFO(dev, "FIFO overwrite interrupt"); > + > + if (status & ATMEL_LCDC_MERI) > + DRM_DEV_INFO(dev, "DMA memory error"); > + > + /* Clear all reported (from ISR) interrupts */ > + regmap_write(lcdc_dc->regmap, ATMEL_LCDC_ICR, isr); > + > + return IRQ_HANDLED; > +} > + [...] > +static int lcdc_dc_modeset_init(struct lcdc_dc *lcdc_dc, struct drm_device *drm) > +{ > + struct drm_bridge *bridge; > + struct drm_panel *panel; > + struct device_node *np; > + struct device *dev; > + int ret; > + > + dev = drm->dev; > + > + drm_mode_config_init(drm); > + drm->mode_config.min_width = lcdc_dc->desc->min_width; > + drm->mode_config.min_height = lcdc_dc->desc->min_height; > + drm->mode_config.max_width = lcdc_dc->desc->max_width; > + drm->mode_config.max_height = lcdc_dc->desc->max_height; > + drm->mode_config.funcs = &mode_config_funcs; > + > + np = dev->of_node; > + /* port at 0 is the output port */ > + ret = drm_of_find_panel_or_bridge(np, 0, 0, &panel, &bridge); > + if (ret && ret != -ENODEV) { > + DRM_DEV_ERROR(dev, "Failed to find panel (%d)\n", ret); > + goto err_out; return ret; > + } > + > + bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_Unknown); drm_of_find_panel_or_bridge() might directly return a bridge. And maybe we should declare a DPI connector. And finally, you can might want to use devm_drm_panel_bridge_add() instead of drm_panel_bridge_add() if (panel) bridge = devm_drm_panel_bridge_add(dev, panel, DRM_MODE_CONNECTOR_DPI); > + if (IS_ERR(bridge)) { > + ret = PTR_ERR(bridge); > + DRM_DEV_ERROR(dev, "Failed to add bridge (%d)", ret); > + goto err_panel_remove; Hm, if drm_panel_bridge_add() failed, you shouldn't call drm_panel_bridge_remove(bridge). You can just do return ret; > + } > + > + lcdc_dc->panel = panel; > + lcdc_dc->bridge = bridge; > + > + ret = drm_simple_display_pipe_init(drm, > + &lcdc_dc->pipe, > + &lcdc_dc_display_funcs, > + lcdc_dc_formats, > + ARRAY_SIZE(lcdc_dc_formats), > + NULL, > + &lcdc_dc->connector); > + if (ret) { > + DRM_DEV_ERROR(dev, "Failed to init display pipe (%d)\n", ret); > + goto err_panel_remove; If you use devm_drm_panel_bridge_add(), you can return directly. > + } > + > + ret = drm_simple_display_pipe_attach_bridge(&lcdc_dc->pipe, bridge); > + if (ret) { > + DRM_DEV_ERROR(dev, "failed to attach bridge (%d)", ret); > + goto err_panel_remove; Ditto. > + } > + > + drm_mode_config_reset(drm); > + > + return 0; > + > +err_panel_remove: > + if (panel) > + drm_panel_bridge_remove(bridge); > + > +err_out: > + return ret; And now you should be able to get rid of the error path entirely. > +} > + > +static int lcdc_dc_load(struct drm_device *drm) > +{ > + const struct of_device_id *match; > + struct platform_device *pdev; > + struct lcdc_dc *lcdc_dc; > + struct device *dev; > + int ret; > + > + dev = drm->dev; > + pdev = to_platform_device(dev); > + > + match = of_match_node(atmel_lcdc_of_match, dev->parent->of_node); > + if (!match) { > + DRM_DEV_ERROR(dev, "invalid compatible string (node=%s)", > + dev->parent->of_node->name); > + return -ENODEV; > + } > + > + if (!match->data) { > + DRM_DEV_ERROR(dev, "invalid lcdc_dc description\n"); > + return -EINVAL; > + } > + > + lcdc_dc = devm_kzalloc(dev, sizeof(*lcdc_dc), GFP_KERNEL); > + if (!lcdc_dc) { > + DRM_DEV_ERROR(dev, "Failed to allocate lcdc_dc\n"); > + return -ENOMEM; > + } > + > + /* reset of lcdc might sleep and require a preemptible task context */ > + INIT_WORK(&lcdc_dc->reset_lcdc_work, reset_lcdc_work); > + > + platform_set_drvdata(pdev, drm); > + dev_set_drvdata(dev, lcdc_dc); > + > + lcdc_dc->mfd_lcdc = dev_get_drvdata(dev->parent); > + drm->dev_private = lcdc_dc; > + > + lcdc_dc->regmap = lcdc_dc->mfd_lcdc->regmap; > + lcdc_dc->desc = match->data; > + lcdc_dc->dev = dev; > + > + lcdc_dc->lcd_supply = devm_regulator_get(dev, "lcd"); > + if (IS_ERR(lcdc_dc->lcd_supply)) { > + DRM_DEV_ERROR(dev, "Failed to get lcd-supply (%ld)\n", > + PTR_ERR(lcdc_dc->lcd_supply)); > + lcdc_dc->lcd_supply = NULL; > + } > + > + lcdc_dc_start_clock(lcdc_dc); Hm, do you really need to call that here? I'd make it part of the runtime PM resume hook, and put a lcdc_dc_stop_clock() in the suspend hook. > + > + pm_runtime_enable(dev); > + > + ret = drm_vblank_init(drm, 1); > + if (ret) { > + DRM_DEV_ERROR(dev, "failed to initialize vblank (%d)\n", > + ret); > + goto err_pm_runtime_disable; > + } > + > + ret = lcdc_dc_modeset_init(lcdc_dc, drm); > + if (ret) { > + DRM_DEV_ERROR(dev, "modeset_init failed (%d)", ret); > + goto err_pm_runtime_disable; > + } > + > + pm_runtime_get_sync(dev); This call will automatically call the runtime PM resume hook, so if you need the clk to be enabled before that point you should put it earlier. Also, you should call pm_runtime_get_sync() in the ->enable() path and pm_runtime_put() in the ->disable() path. > + ret = drm_irq_install(drm, lcdc_dc->mfd_lcdc->irq); > + pm_runtime_put_sync(dev); > + if (ret < 0) { > + DRM_DEV_ERROR(dev, "Failed to install IRQ (%d)\n", ret); > + > + goto err_pm_runtime_disable; > + } > + > + /* > + * Passing in 16 here will make the RGB656 mode the default > + * Passing in 32 will use XRGB8888 mode > + */ > + drm_fb_cma_fbdev_init(drm, 16, 0); > + > + drm_kms_helper_poll_init(drm); > + > + lcdc_dc->fbdev = drm_fbdev_cma_init(drm, 8, 1); > + if (IS_ERR(lcdc_dc->fbdev)) { > + ret = PTR_ERR(lcdc_dc->fbdev); > + DRM_DEV_ERROR(dev, "Failed to init FB CMA area (%d)", ret); > + goto err_irq_uninstall; > + } > + > + drm_helper_hpd_irq_event(drm); > + > + return 0; > + > +err_irq_uninstall: > + pm_runtime_get_sync(dev); > + drm_irq_uninstall(drm); > + pm_runtime_put_sync(dev); > + > +err_pm_runtime_disable: > + pm_runtime_disable(dev); > + lcdc_dc_stop_clock(lcdc_dc); > + > + cancel_work_sync(&lcdc_dc->reset_lcdc_work); Isn't there a race here? What if there was a work queued but you disabled the clk? I guess reg read/write accesses might fail (don't know how bad this can go though). > + > + return ret; > +} > + > +static void lcdc_dc_unload(struct drm_device *dev) > +{ > + struct lcdc_dc *lcdc_dc = dev->dev_private; > + > + drm_fb_cma_fbdev_fini(dev); > + flush_work(&lcdc_dc->reset_lcdc_work); > + drm_kms_helper_poll_fini(dev); > + if (lcdc_dc->panel) > + drm_panel_bridge_remove(lcdc_dc->bridge); You can drop that one if you use the devm_ version. > + drm_mode_config_cleanup(dev); > + > + pm_runtime_get_sync(dev->dev); > + drm_irq_uninstall(dev); > + pm_runtime_put_sync(dev->dev); > + > + dev->dev_private = NULL; > + > + pm_runtime_disable(dev->dev); > + lcdc_dc_stop_clock(lcdc_dc); > + cancel_work_sync(&lcdc_dc->reset_lcdc_work); And again, it might be too late. Should be moved just after disabling the IRQ, since this is the only path where you queue this work. > +} > + > + > +static int lcdc_dc_probe(struct platform_device *pdev) > +{ > + struct drm_device *drm; > + struct device *dev; > + int ret; > + > + dev = &pdev->dev; > + > + drm = drm_dev_alloc(&lcdc_dc_drm_driver, dev); > + if (IS_ERR(drm)) { > + DRM_DEV_ERROR(dev, "Failed to allocate drm device\n"); > + return PTR_ERR(drm); > + } > + > + ret = lcdc_dc_load(drm); > + if (ret) > + goto err_put_ref; > + > + ret = drm_dev_register(drm, 0); > + if (ret) { > + DRM_DEV_ERROR(dev, "Failed to register drm (%d)\n", ret); > + goto err_unload; > + } > + > + return 0; > + > +err_unload: > + lcdc_dc_unload(drm); > + > +err_put_ref: > + drm_dev_put(drm); > + return ret; > +} That's all I see for now, but keep in mind that I don't know much about the DRM simple interface, so you'd better wait for a review from someone who knows better (Noralf?). Regards, Boris