From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sam Ravnborg Subject: Re: [PATCH 2/3] drm/bridge: add it6505 driver Date: Wed, 8 May 2019 23:07:31 +0200 Message-ID: <20190508210731.GA19781@ravnborg.org> References: <1557301722-20827-1-git-send-email-allen.chen@ite.com.tw> <1557301722-20827-3-git-send-email-allen.chen@ite.com.tw> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Content-Disposition: inline In-Reply-To: <1557301722-20827-3-git-send-email-allen.chen@ite.com.tw> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: allen Cc: Archit Taneja , Jitao Shi , Yilun Lin , open list , "open list:DRM DRIVERS" , David Airlie , "moderated list:ARM/Mediatek SoC support" , Laurent Pinchart , Pi-Hsun Shih , Matthias Brugger , "moderated list:ARM/Mediatek SoC support" List-Id: linux-mediatek@lists.infradead.org SGkgYWxsZW4uCgpUaGFua3MgZm9yIHRoaXMgZmluZSBwYXRjaC4KQSBmZXcgY29tbWVudHMgZm9s bG93cy4KCkNvbnNpZGVyIHRvIHVzZSBEUk1fREVWX0VSUk9SIGFuZCBmcmllbmRzLgpUaGVuIHlv dSBnZXQgdGhlIGRldmljZW5hbWUgaW5jbHVkZWQgaW4gbG9nZ2luZwphbmQgdGhpcyBtYWtlcyBp dCBtdWNoIGVhc2llciB0byBmaW5kIHJlbGV2YW50IGVudHJpZXMuCgpPbiBXZWQsIE1heSAwOCwg MjAxOSBhdCAwMzo0ODo0MVBNICswODAwLCBhbGxlbiB3cm90ZToKPiBGcm9tOiBBbGxlbiBDaGVu IDxhbGxlbi5jaGVuQGl0ZS5jb20udHc+Cj4gCj4gVGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBp VEUgSVQ2NTA1Lgo+IFRoaXMgZGV2aWNlIGNhbiBjb252ZXJ0IERQSSBzaWduYWwgdG8gRFAgb3V0 cHV0Lgo+IAo+IFNpZ25lZC1vZmYtYnk6IEppdGFvIFNoaSA8aml0YW8uc2hpQG1lZGlhdGVrLmNv bT4KPiBTaWduZWQtb2ZmLWJ5OiBZaWx1biBMaW4gPHlsbGluQGdvb2dsZS5jb20+Cj4gU2lnbmVk LW9mZi1ieTogQWxsZW4gQ2hlbiA8YWxsZW4uY2hlbkBpdGUuY29tLnR3Pgo+IC0tLQo+ICBkcml2 ZXJzL2dwdS9kcm0vYnJpZGdlL0tjb25maWcgICAgICB8ICAgMjIgKwo+ICBkcml2ZXJzL2dwdS9k cm0vYnJpZGdlL01ha2VmaWxlICAgICB8ICAgIDEgKwo+ICBkcml2ZXJzL2dwdS9kcm0vYnJpZGdl L2l0ZS1pdDY1MDUuYyB8IDI2MzcgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysK PiAgMyBmaWxlcyBjaGFuZ2VkLCAyNjYwIGluc2VydGlvbnMoKykKPiAgY3JlYXRlIG1vZGUgMTAw NjQ0IGRyaXZlcnMvZ3B1L2RybS9icmlkZ2UvaXRlLWl0NjUwNS5jCj4gCj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvS2NvbmZpZyBiL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2Uv S2NvbmZpZwo+IGluZGV4IDljOWM0ZGYuLmQxMmU0OGMgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9n cHUvZHJtL2JyaWRnZS9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9LY29u ZmlnCj4gQEAgLTQzLDYgKzQzLDI4IEBAIGNvbmZpZyBEUk1fRFVNQl9WR0FfREFDCj4gIAkgIFN1 cHBvcnQgZm9yIG5vbi1wcm9ncmFtbWFibGUgUkdCIHRvIFZHQSBEQUMgYnJpZGdlcywgc3VjaCBh cyBBREkKPiAgCSAgQURWNzEyMywgVEkgVEhTODEzNCBhbmQgVEhTODEzNSBvciBwYXNzaXZlIHJl c2lzdG9yIGxhZGRlciBEQUNzLgo+ICAKPiArY29uZmlnIERSTV9JVEVfSVQ2NTA1Cj4gKwl0cmlz dGF0ZSAiSVRFIElUNjUwNSBEUCBicmlkZ2UiCj4gKwlkZXBlbmRzIG9uIE9GCj4gKwlzZWxlY3Qg RFJNX0tNU19IRUxQRVIKPiArCWhlbHAKPiArCSAgSVRFIElUNjUwNSBEUCBicmlkZ2UgY2hpcCBk cml2ZXIuCgpXaHkgaXMgaXQgcmVsZXZhbnQgdG8gaGF2ZSB0aGVzZSBmZWF0dXJlcyBhcyBmZWF0 dXJlcwp0aGF0IGNhbiBiZSBlbmFiZWQvZGlzYWJsZWQgb24gS2NvbmZpZyBsZXZlbD8KSXQgaXMg bGlrZWx5IG1vcmUgZmxleGlibGUgdG8gZG8gaXQgcnVuLXRpbWUKaWYgbmVlZGVkIHRvIHR1cm4g dGhlbSBvZmYuCkFuZCBpdCB3b3VsZCBzaW1wbGlmeSB0aGUgY29kZS4KCj4gKwo+ICtjb25maWcg RFJNX0lURV9JVDY1MDVfRU5IRENQCj4gKwl0cmlzdGF0ZSAiRW5hYmxlIElUNjUwNSBIRENQIGZ1 bmN0aW9uIgo+ICsJZGVwZW5kcyBvbiBEUk1fSVRFX0lUNjUwNQo+ICsJZGVmYXVsdCB5Cj4gKwo+ ICtjb25maWcgRFJNX0lURV9JVDY1MDVfRU5BVUQKPiArICAgICAgICB0cmlzdGF0ZSAiRW5hYmxl IElUNjUwNSBhdWRpbyBmdW5jdGlvbiIKPiArICAgICAgICBkZXBlbmRzIG9uIERSTV9JVEVfSVQ2 NTA1Cj4gKyAgICAgICAgZGVmYXVsdCB5Cj4gKwo+ICtjb25maWcgRFJNX0lURV9JVDY1MDVfRU5Q V1JPTk9GRgo+ICsgICAgICAgIHRyaXN0YXRlICJFbmFibGUgSVQ2NTA1IHBvd2VyIG9uL29mZiBm dW5jdGlvbiIKPiArICAgICAgICBkZXBlbmRzIG9uIERSTV9JVEVfSVQ2NTA1Cj4gKyAgICAgICAg ZGVmYXVsdCB5Cj4gKwo+ICBjb25maWcgRFJNX0xWRFNfRU5DT0RFUgo+ICAJdHJpc3RhdGUgIlRy YW5zcGFyZW50IHBhcmFsbGVsIHRvIExWRFMgZW5jb2RlciBzdXBwb3J0Igo+ICAJZGVwZW5kcyBv biBPRgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL01ha2VmaWxlIGIvZHJp dmVycy9ncHUvZHJtL2JyaWRnZS9NYWtlZmlsZQo+IGluZGV4IDQ5MzRmY2YuLmY1YWJjYTUgMTAw NjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9NYWtlZmlsZQo+ICsrKyBiL2RyaXZl cnMvZ3B1L2RybS9icmlkZ2UvTWFrZWZpbGUKPiBAQCAtMiw2ICsyLDcgQEAKPiAgb2JqLSQoQ09O RklHX0RSTV9BTkFMT0dJWF9BTlg3OFhYKSArPSBhbmFsb2dpeC1hbng3OHh4Lm8KPiAgb2JqLSQo Q09ORklHX0RSTV9DRE5TX0RTSSkgKz0gY2Rucy1kc2kubwo+ICBvYmotJChDT05GSUdfRFJNX0RV TUJfVkdBX0RBQykgKz0gZHVtYi12Z2EtZGFjLm8KPiArb2JqLSQoQ09ORklHX0RSTV9JVEVfSVQ2 NTA1KSArPSBpdGUtaXQ2NTA1Lm8KPiAgb2JqLSQoQ09ORklHX0RSTV9MVkRTX0VOQ09ERVIpICs9 IGx2ZHMtZW5jb2Rlci5vCj4gIG9iai0kKENPTkZJR19EUk1fTUVHQUNISVBTX1NURFBYWFhYX0dF X0I4NTBWM19GVykgKz0gbWVnYWNoaXBzLXN0ZHB4eHh4LWdlLWI4NTB2My1mdy5vCj4gIG9iai0k KENPTkZJR19EUk1fTlhQX1BUTjM0NjApICs9IG54cC1wdG4zNDYwLm8KPiBkaWZmIC0tZ2l0IGEv ZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9pdGUtaXQ2NTA1LmMgYi9kcml2ZXJzL2dwdS9kcm0vYnJp ZGdlL2l0ZS1pdDY1MDUuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4u MTMwNzlhOAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL2l0 ZS1pdDY1MDUuYwo+IEBAIC0wLDAgKzEsMjYzNyBAQAo+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRp ZmllcjogR1BMLTIuMAo+ICsvKgo+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTgsIFRoZSBMaW51eCBG b3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgo+ICsgKi8KPiArI2luY2x1ZGUgPGxpbnV4 L2JpdHMuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9k ZXZpY2UuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgo+ICsjaW5jbHVkZSA8bGludXgvZXh0 Y29uLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9mcy5oPgo+ICsjaW5jbHVkZSA8bGludXgvZ3Bpby9j b25zdW1lci5oPgo+ICsjaW5jbHVkZSA8bGludXgvaTJjLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9p bnRlcnJ1cHQuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5jbHVkZSA8bGlu dXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yZWdtYXAuaD4KPiArI2luY2x1ZGUgPGxp bnV4L3JlZ3VsYXRvci9jb25zdW1lci5oPgo+ICsjaW5jbHVkZSA8bGludXgvc2VtYXBob3JlLmg+ Cj4gKyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgo+ICsjaW5jbHVkZSA8Y3J5cHRvL2hhc2guaD4K PiArI2luY2x1ZGUgPGNyeXB0by9zaGEuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1QLmg+Cj4gKyNp bmNsdWRlIDxkcm0vZHJtX2F0b21pY19oZWxwZXIuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1fY3J0 Yy5oPgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9jcnRjX2hlbHBlci5oPgo+ICsjaW5jbHVkZSA8ZHJt L2RybV9kcF9oZWxwZXIuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1fZWRpZC5oPgpQbGVhc2UgcHV0 IGEgYmxhbmsgbGluZSBiZXR3ZWVuIHRoZSBpbmRpdmlkdWFsIGJsb2NrcwpvZiBpbmNsdWRlIGZp bGVzLgpTbyBhbGwgI2luY2x1ZGUgPGxpbnV4Ly4uLiBjb21lbnMgZmlyc3QKClRoZW4gI2luY2x1 ZGUgPGNyeXB0by8uLi4KCkFuZCBmaW5hbGx5ICNpbmNsdWRlIDxkcm0vLi4uCgpVc2Ugb2YgZHJt UC5oIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSBkbyBub3QgdXNlIGl0LgpZb3UgbmVlZCB0byBhZGQg Zm9yd2FyZHMgb3IgaW5jbHVkZXMgdG8gYXZvaWRzLgoKCj4gKwo+ICsjZGVmaW5lIEFYIDAKPiAr I2RlZmluZSBCWCAxCj4gKyNkZWZpbmUgQVVEU0VMIEkyUwo+ICsjZGVmaW5lIEFVRFRZUEUgTFBD TQo+ICsjZGVmaW5lIEFVREZTIEFVRDQ4Swo+ICsjZGVmaW5lIEFVRENIIDIKPiArLyogMDogU3Rh bmRhcmQgSTJTOzE6IDMyYml0IEkyUyAqLwo+ICsjZGVmaW5lIEkyU0lOUFVURk1UIDEKPiArLyog MDogTGVmdC1qdXN0aWZpZWQ7MTogUmlnaHQtanVzdGlmaWVkICovCj4gKyNkZWZpbmUgSTJTSlVT VElGSUVEIDAKPiArLyogMDogRGF0YSBkZWxheSAxVCBjb3JyZXNwb25kIHRvIFdTOzE6IE5vIGRh dGEgZGVsYXkgY29ycmVzcG9uZCB0byBXUyAqLwo+ICsjZGVmaW5lIEkyU0RBVEFERUxBWSAwCj4g Ky8qIDA6IGlzIGxlZnQgY2hhbm5lbDsxOiBpcyByaWdodCBjaGFubmVsICovCj4gKyNkZWZpbmUg STJTV1NDSEFOTkVMIDAKPiArLyogMDogTVNCIHNoaWZ0IGZpcnN0OzE6IExTQiBzaGlmdCBmaXJz dCAqLwo+ICsjZGVmaW5lIEkyU0RBVEFTRVEgMAo+ICsKPiArI2RlZmluZSBMQU5FU1dBUCAwCj4g KyNkZWZpbmUgTEFORSA0Cj4gKyNkZWZpbmUgX0hCUiAxCj4gKyNkZWZpbmUgRU5IRlJBTUUgMQo+ ICsjZGVmaW5lIEVOU1NDIDEKPiArCj4gKyNkZWZpbmUgRkxBR1RSQUlORE9XTiAxMDAKPiArI2Rl ZmluZSBUUkFJTkZBSUxDTlQgNQo+ICsjZGVmaW5lIEFVWF9XQUlUX1RJTUVPVVRfTVMgMTUKPiAr I2RlZmluZSBQQ0xLX0RFTEFZIDEKPiArI2RlZmluZSBQQ0xLX0lOViAwCj4gKyNkZWZpbmUgRURJ RFJFVFJZVElNRSA1Cj4gKyNkZWZpbmUgU0hPV1ZJREVPVElNSU5HIDIKPiArI2RlZmluZSBQV1JP RkZSRVRSWVRJTUUgNQo+ICsKPiArLyogQVggb3IgQlggKi8KPiArI2RlZmluZSBDSElQX1ZFUlNJ T04gQlgKCklmIHRoaXMgZHJpdmVyIGlzIGZvciBCWCBvbmx5IHRoZW4gZHJvcCB0aGUgQVggcmVs ZWF0ZWQgY29kZS4KVGhpcyB3b3VsZCBzaW1wbGlmeSB0aGUgZHJpdmVyLgoKSWYgdGhpcyBpcyBy ZWFsbHkgbmVlZGVkIHRoZW4gcHJvdmlkZSBhbiBlbXB0eSB2YXJpYW50IG9mCml0NjUwNV90ZXJt aW5hdGlvbigpIGZvciBBWCwgdG8gc2ltcGxpZnkgdGhlIGNhbGwgc2l0ZXMuCgpBbmQgaXQ2NTA1 X3Rlcm1pbmF0aW9uKCkgY2FsbHMgZm9yIHR3byBmdW5jdGlvbnMgc28gd2UKdm9pZCBhIGJvb2wg cGFyYW1ldGVyIHRoYXQgbWFrZXMgdGhlIGZ1bmN0aW9uIGRvIHR3bwpkaWZmZXJlbnQgdGhpbmdz LgoKPiArCj4gKy8qIGlmIHVzZSB0aGlzIGRlZmluZSB3aWxsIHBvd2VyIG9uIGluIHByb2JlICov Cj4gKy8qICNkZWZpbmUgVEVTVF9NT0RFICovCj4gKwo+ICsvKiBpZiB1c2UgdGhpcyBkZWZpbmUg d2lsbCBlbmFibGUgQVVYIGRlYnVnIG9wdGlvbiAqLwo+ICsvKiAjZGVmaW5lIEVOQVVYX1RSQU5T RkVSX0RFQlVHICovCj4gKwo+ICsvKiBpZiB1c2UgdGhpcyBkZWZpbmUgd2lsbCBlbmFibGUgU0hB IGRlYnVnICovCj4gKy8qICNkZWZpbmUgU0hBX0RFQlVHICovCkNvbnNpZGVyIGhvdyBtdWNoIG9m IHRoaXMgcmVhbGx5IGJlbG9uZ3MgaW4gYSBwcm9kdWN0aW9uIGRyaXZlci4KSWYgcmVsZXZhbnQg Y29uc2lkZXIgdG8gYWRkIHNvbWUgd2F5IHRvIGVuYWJsZSB0aGlzIHJ1bnRpbWUuCj4gKwo+ICtl bnVtIHN5c19zdGF0dXMgewo+ICsJU1lTX1VOUExVRyA9IDAsCj4gKwlTWVNfSFBELAo+ICsJU1lT X0FVVE9UUkFJTiwKPiArCVNZU19XQUlULAo+ICsJU1lTX1RSQUlORkFJTCwKPiArCVNZU19SZUhE Q1AsCj4gKwlTWVNfUFdSRE4sCj4gKwlTWVNfTk9ST1AsCj4gKwlTWVNfVW5rbm93biwKPiArfTsK PiArCj4gK2VudW0gaXQ2NTA1X2F1ZF9zZWwgewo+ICsJSTJTID0gMCwKPiArCVNQRElGLAo+ICt9 Owo+ICsKPiArZW51bSBpdDY1MDVfYXVkX2ZzIHsKPiArCUFVRDI0SyA9IDB4NiwKPiArCUFVRDMy SyA9IDB4MywKPiArCUFVRDQ4SyA9IDB4MiwKPiArCUFVRDk2SyA9IDB4QSwKPiArCUFVRDE5Mksg PSAweEUsCj4gKwlBVUQ0NFAxSyA9IDB4MCwKPiArCUFVRDg4UDJLID0gMHg4LAo+ICsJQVVEMTc2 UDRLID0gMHhDLAo+ICt9Owo+ICsKPiArZW51bSBpdDY1MDVfYXVkX3R5cGUgewo+ICsJTFBDTSA9 IDAsCj4gKwlOTFBDTSwKPiArCURTUywKPiArCUhCUiwKPiArfTsKPiArCj4gK2VudW0gYXVkX3dv cmRfbGVuZ3RoIHsKPiArCUFVRDE2QklUID0gMCwKPiArCUFVRDE4QklULAo+ICsJQVVEMjBCSVQs Cj4gKwlBVUQyNEJJVCwKPiArfTsKPiArCj4gKy8qIEF1ZGlvIFNhbXBsZSBXb3JkIExlbmd0aDog QVVEMTZCSVQsIEFVRDE4QklULCBBVUQyMEJJVCwgQVVEMjRCSVQgKi8KPiArI2RlZmluZSBBVURX T1JETEVOR1RIIEFVRDI0QklUCj4gKwo+ICtzdHJ1Y3QgaXQ2NTA1X3BsYXRmb3JtX2RhdGEgewo+ ICsJc3RydWN0IHJlZ3VsYXRvciAqcHdyMTg7Cj4gKwlzdHJ1Y3QgcmVndWxhdG9yICpvdmRkOwo+ ICsJc3RydWN0IGdwaW9fZGVzYyAqZ3Bpb2RfaHBkOwo+ICsJc3RydWN0IGdwaW9fZGVzYyAqZ3Bp b2RfcGQ7CgpncGlvZF9wZCBpcyBub3QgdXNlZCBhbmQgY2FuIGJlIGRlbGV0ZWQuCgo+ICsJc3Ry dWN0IGdwaW9fZGVzYyAqZ3Bpb2RfcmVzZXQ7Cj4gKwo+ICsJaW50IGhwZF9pcnE7Cj4gKwlpbnQg aW50cF9pcnE7CmhwZF9pcnEgYW5kIGludHBfaXJxIGFyZSBvbmx5IHVzZWQgaW4gb25lIGZ1bmN0 aW9uLgpEcm9wIHRoZW0gZnJvbSBpdDY1MDVfcGxhdGZvcm1fZGF0YSBhbmQgdXNlIGxvY2FsIHZh cmlhYmxlcy4KCj4gK307Cj4gKwo+ICtzdHJ1Y3QgaXQ2NTA1X2RwX3BvcnQgewo+ICsJc3RydWN0 IGl0NjUwNSAqaXQ2NTA1X2RwOwo+ICsJc3RydWN0IG5vdGlmaWVyX2Jsb2NrIGV2ZW50X25iOwo+ ICsJc3RydWN0IGV4dGNvbl9kZXYgKmV4dGNvbjsKPiArCXN0cnVjdCB3b3JrX3N0cnVjdCBleHRj b25fd3E7Cj4gKwl1OCBpZDsKSXQgZGlkIG5vdCBzZWUgdGhpcyB1c2VkLCBvbmx5IGFzc2lnbmVk LiBNYXliZSBJIG1pc3NlZCBzb21ldGhpbmc/Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgaXQ2NTA1IHsK PiArCXN0cnVjdCBkcm1fZHBfYXV4IGF1eDsKPiArCXN0cnVjdCBkcm1fYnJpZGdlIGJyaWRnZTsK PiArCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7Cj4gKwlzdHJ1Y3QgZWRpZCAqZWRpZDsKPiAr CXN0cnVjdCBkcm1fY29ubmVjdG9yIGNvbm5lY3RvcjsKPiArCXN0cnVjdCBkcm1fZHBfbGluayBs aW5rOwo+ICsJc3RydWN0IGl0NjUwNV9wbGF0Zm9ybV9kYXRhIHBkYXRhOwo+ICsJc3RydWN0IG11 dGV4IGxvY2s7Ckkgd291bGQgYmUgaGVscGZ1bGwgd2l0aCBhIGNvbW1lbnQgd2hhdCB0aGUgbG9j ayBwcm90ZWN0cy4KCj4gKwlzdHJ1Y3QgcmVnbWFwICpyZWdtYXA7Cj4gKwlzdHJ1Y3QgaXQ2NTA1 X2RwX3BvcnQgKnBvcnQ7Cj4gKwkvKiB0aHJlYWQgc2VxdWVuY2UgY29udHJvbCAqLwo+ICsJc3Ry dWN0IHNlbWFwaG9yZSBzZW1fbm90aWZpZXI7Cj4gKwo+ICsJdTggZHBjZFtEUF9SRUNFSVZFUl9D QVBfU0laRV07Cj4gKwllbnVtIHN5c19zdGF0dXMgc3RhdHVzOwo+ICsJdTggZHVtcGRwY2RbMzBd Owo+ICsJdTggZHBjZF9yZXY7CmRwY2RfcmV2IGlzIG9ubHkgdXNlZCBpbiBvbmUgZnVuY3Rpb24u CkRyb3AgaXQgYW5kIHVzZSBsb2NhbCB2YXJpYWJlbC4KCkkgZGlkIG5vdCBjaGVjayBmdXJ0aGVy IC0gcGxlYXNlIHZlcmlmeSB0aGF0IGFsbAptZW1iZXJzIGFyZSB1c2VkIGFuZCBhcmUgcmVsZXZh bnQgdG8gaGF2ZSBpbiB0aGlzCnN0cnVjdC4KCj4gKwlib29sIGhicjsKPiArCXU4IGxhbmU7Cj4g Kwl1OCBlbl9zc2M7Cj4gKwlib29sIGVuX2hmcmFtZTsKPiArCWJvb2wgbGFuZXN3YXA7Cj4gKwo+ ICsJZW51bSBpdDY1MDVfYXVkX3NlbCBhdWRfc2VsOwo+ICsJZW51bSBpdDY1MDVfYXVkX2ZzIGF1 ZF9mczsKPiArCWVudW0gaXQ2NTA1X2F1ZF90eXBlIGF1ZF90eXBlOwo+ICsJdTggYXVkX2NoOwo+ ICsJdTggaTJzX2lucHV0X2ZtdDsKPiArCXU4IGkyc19qdXN0aWZpZWQ7Cj4gKwl1OCBpMnNfZGF0 YV9kZWxheTsKPiArCXU4IGkyc193c19jaGFubmVsOwo+ICsJdTggaTJzX2RhdGFfc2VxOwo+ICsJ dTggdmlkc3RhYmxlX2RvbmU7Cj4gKwllbnVtIGF1ZF93b3JkX2xlbmd0aCBhdWR3b3JkbGVuZ3Ro Owo+ICsJdTggY250ZnNtOwo+ICsJYm9vbCBjcF9yZWFkeTsKPiArCXVuc2lnbmVkIGludCBic3Rh dHVzOwo+ICsJYm9vbCBjcF9kb25lOwo+ICsJdTggZG93bnN0cmVhbV9yZXBlYXRlcjsKPiArCXU4 IGFtMFs4XTsKPiArCXU4IGJpbmZvWzJdOwo+ICsJdTgga3N2bGlzdFs1ICogMTJdOwo+ICsJdW5z aWduZWQgaW50IHNoYVs1XTsKPiArCXVuc2lnbmVkIGludCB3WzgwXTsKPiArCXU4IHNoYWlucHV0 WzY0XTsKPiArCXU4IGF2WzVdWzRdOwo+ICsJdTggYnZbNV1bNF07Cj4gKwl1OCBwYXNzc2hhOwo+ ICsJYm9vbCBwb3dlcmVkOwo+ICsJLyogaXQ2NTA1IGRyaXZlciBob2xkIG9wdGlvbiAqLwo+ICsJ dW5zaWduZWQgaW50IGl0NjUwNV9kcnZfaG9sZDsKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgaXQ2 NTA1X3Bvd2Vyb24oc3RydWN0IGl0NjUwNSAqaXQ2NTA1KTsKPiArI2lmZGVmIENPTkZJR19EUk1f SVRFX0lUNjUwNV9FTlBXUk9OT0ZGCj4gK3N0YXRpYyBpbnQgaXQ2NTA1X3Bvd2Vyb2ZmKHN0cnVj dCBpdDY1MDUgKml0NjUwNSk7Cj4gKyNlbmRpZgo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBy ZWdtYXBfcmFuZ2UgaXQ2NTA1X2JyaWRnZV92b2xhdGlsZV9yYW5nZXNbXSA9IHsKPiArCXsgLnJh bmdlX21pbiA9IDAsIC5yYW5nZV9tYXggPSAweEZGIH0sCj4gK307Cj4gKwo+ICtzdGF0aWMgY29u c3Qgc3RydWN0IHJlZ21hcF9hY2Nlc3NfdGFibGUgaXQ2NTA1X2JyaWRnZV92b2xhdGlsZV90YWJs ZSA9IHsKPiArCS55ZXNfcmFuZ2VzID0gaXQ2NTA1X2JyaWRnZV92b2xhdGlsZV9yYW5nZXMsCj4g Kwkubl95ZXNfcmFuZ2VzID0gQVJSQVlfU0laRShpdDY1MDVfYnJpZGdlX3ZvbGF0aWxlX3Jhbmdl cyksCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHJlZ21hcF9jb25maWcgaXQ2NTA1 X2JyaWRnZV9yZWdtYXBfY29uZmlnID0gewo+ICsJLnJlZ19iaXRzID0gOCwKPiArCS52YWxfYml0 cyA9IDgsCj4gKwkudm9sYXRpbGVfdGFibGUgPSAmaXQ2NTA1X2JyaWRnZV92b2xhdGlsZV90YWJs ZSwKPiArCS5jYWNoZV90eXBlID0gUkVHQ0FDSEVfTk9ORSwKPiArfTsKPiArCj4gK3N0YXRpYyBp bnQgZHB0eHJkKHN0cnVjdCBpdDY1MDUgKml0NjUwNSwgdW5zaWduZWQgaW50IHJlZ19hZGRyLAo+ ICsJCSAgdW5zaWduZWQgaW50ICp2YWx1ZSkKPiArewo+ICsJaW50IGVycjsKPiArCj4gKwllcnIg PSByZWdtYXBfcmVhZChpdDY1MDUtPnJlZ21hcCwgcmVnX2FkZHIsIHZhbHVlKTsKPiArCWlmIChl cnIgPCAwKSB7Cj4gKwkJRFJNX0VSUk9SKCIlcyByZWFkIGZhaWwgZXJyIHJlZ19hZGRyWzB4JXhd IGVycjolZFxuIiwKPiArCQkJICBfX2Z1bmNfXywgcmVnX2FkZHIsIGVycik7Cj4gKwkJcmV0dXJu IGVycjsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgaXQ2 NTA1X2R1bXAoc3RydWN0IGl0NjUwNSAqaXQ2NTA1KQo+ICt7Cj4gKwl1bnNpZ25lZCBpbnQgdmFs dWUsIGk7Cj4gKwo+ICsJRFJNX0RFQlVHX0RSSVZFUigiXG4tLS0tLS0tLS0tJXMgc3RhcnQtLS0t LS0tLS0tXG4iLCBfX2Z1bmNfXyk7Cj4gKwlmb3IgKGkgPSAwOyBpIDw9IDB4ZmY7IGkrKykgewo+ ICsJCWRwdHhyZChpdDY1MDUsIGksICZ2YWx1ZSk7Cj4gKwkJRFJNX0RFQlVHX0RSSVZFUigiJXNb MHgleF0gPSAweCV4XG4iLCBfX2Z1bmNfXywgaSwgdmFsdWUpOwo+ICsJfQo+ICsJRFJNX0RFQlVH X0RSSVZFUigiXG4tLS0tLS0tLS0tJXMgZW5kLS0tLS0tLS0tLVxuXG4iLCBfX2Z1bmNfXyk7Cj4g K30KQXJlIHRoZXNlIGhlYWRlcnMgcmVhbGx5IG5lZWRlZCBpbiBhIHByb2R1Y3Rpb24gZHJpdmVy PwoKPiArCj4gK3N0YXRpYyBpbnQgZHB0eHdyKHN0cnVjdCBpdDY1MDUgKml0NjUwNSwgdW5zaWdu ZWQgaW50IHJlZ19hZGRyLAo+ICsJCSAgdW5zaWduZWQgaW50IHJlZ192YWwpCj4gK3sKPiArCWlu dCBlcnI7Cj4gKwo+ICsJZXJyID0gcmVnbWFwX3dyaXRlKGl0NjUwNS0+cmVnbWFwLCByZWdfYWRk ciwgcmVnX3ZhbCk7Cj4gKwo+ICsJaWYgKGVyciA8IDApIHsKPiArCQlEUk1fRVJST1IoIiVzIHdy aXRlIGZhaWwgZXJyIHJlZ1sweCV4XSA9IDB4JXggZXJyID0gJWRcbiIsCj4gKwkJCV9fZnVuY19f LCByZWdfYWRkciwgcmVnX3ZhbCwgZXJyKTsKPiArCQlyZXR1cm4gZXJyOwo+ICsJfQo+ICsKPiAr CXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGRwdHhzZXQoc3RydWN0IGl0NjUwNSAq aXQ2NTA1LCB1bnNpZ25lZCBpbnQgcmVnLCB1bnNpZ25lZCBpbnQgbWFzaywKPiArCQkgICB1bnNp Z25lZCBpbnQgdmFsdWUpCj4gK3sKPiArCWludCBlcnI7Cj4gKwo+ICsJZXJyID0gcmVnbWFwX3Vw ZGF0ZV9iaXRzKGl0NjUwNS0+cmVnbWFwLCByZWcsIG1hc2ssIHZhbHVlKTsKPiArCWlmIChlcnIg PCAwKSB7Cj4gKwkJRFJNX0VSUk9SKCIlcyB3cml0ZSBmYWlsIGVyciAlZFxuIiwgX19mdW5jX18s IGVycik7Cj4gKwkJcmV0dXJuIGVycjsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK PiArc3RhdGljIGlubGluZSBzdHJ1Y3QgaXQ2NTA1ICpjb25uZWN0b3JfdG9faXQ2NTA1KHN0cnVj dCBkcm1fY29ubmVjdG9yICpjKQo+ICt7Cj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGMsIHN0cnVj dCBpdDY1MDUsIGNvbm5lY3Rvcik7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IGl0 NjUwNSAqYnJpZGdlX3RvX2l0NjUwNShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlKQo+ICt7Cj4g KwlyZXR1cm4gY29udGFpbmVyX29mKGJyaWRnZSwgc3RydWN0IGl0NjUwNSwgYnJpZGdlKTsKPiAr fQo+ICsKPiArc3RhdGljIHZvaWQgaXQ2NTA1X2luaXRfZnNtKHN0cnVjdCBpdDY1MDUgKml0NjUw NSkKPiArewo+ICsJaXQ2NTA1LT5hdWRfc2VsID0gQVVEU0VMOwo+ICsJaXQ2NTA1LT5hdWRfZnMg PSBBVURGUzsKPiArCWl0NjUwNS0+YXVkX2NoID0gQVVEQ0g7Cj4gKwlpdDY1MDUtPmF1ZF90eXBl ID0gQVVEVFlQRTsKPiArCWl0NjUwNS0+aTJzX2lucHV0X2ZtdCA9IEkyU0lOUFVURk1UOwo+ICsJ aXQ2NTA1LT5pMnNfanVzdGlmaWVkID0gSTJTSlVTVElGSUVEOwo+ICsJaXQ2NTA1LT5pMnNfZGF0 YV9kZWxheSA9IEkyU0RBVEFERUxBWTsKPiArCWl0NjUwNS0+aTJzX3dzX2NoYW5uZWwgPSBJMlNX U0NIQU5ORUw7Cj4gKwlpdDY1MDUtPmkyc19kYXRhX3NlcSA9IEkyU0RBVEFTRVE7Cj4gKwlpdDY1 MDUtPmF1ZHdvcmRsZW5ndGggPSBBVURXT1JETEVOR1RIOwo+ICsKPiArCWl0NjUwNS0+c3RhdHVz ID0gU1lTX1Vua25vd247Cj4gKwlpdDY1MDUtPmhiciA9IF9IQlI7Cj4gKwlpdDY1MDUtPmxhbmUg PSBMQU5FOwo+ICsJaXQ2NTA1LT5lbl9zc2MgPSBFTlNTQzsKPiArCWl0NjUwNS0+ZW5faGZyYW1l ID0gRU5IRlJBTUU7Cj4gKwlpdDY1MDUtPmxhbmVzd2FwID0gTEFORVNXQVA7Cj4gKwlpdDY1MDUt PnZpZHN0YWJsZV9kb25lID0gMDsKPiArfQo+ICsKPiArI2lmIChDSElQX1ZFUlNJT04gPT0gQlgp Cj4gK3N0YXRpYyB2b2lkIGl0NjUwNV90ZXJtaW5hdGlvbihzdHJ1Y3QgaXQ2NTA1ICppdDY1MDUs IGJvb2wgcykKPiArewo+ICsJRFJNX0RFQlVHX0RSSVZFUigiJXMgc3dpdGNoISFcbiIsIF9fZnVu Y19fKTsKPiArCWlmIChzKSB7Cj4gKwkJZHB0eHNldChpdDY1MDUsIDB4NUQsIDB4ODAsIDB4MDAp Owo+ICsJCWRwdHhzZXQoaXQ2NTA1LCAweDVFLCAweDAyLCAweDAyKTsKPiArCQlEUk1fREVCVUdf RFJJVkVSKCIlcyBPTiEhXG4iLCBfX2Z1bmNfXyk7Cj4gKwl9IGVsc2Ugewo+ICsJCWRwdHhzZXQo aXQ2NTA1LCAweDVELCAweDgwLCAweDgwKTsKPiArCQlkcHR4c2V0KGl0NjUwNSwgMHg1RSwgMHgw MiwgMHgwMCk7Cj4gKwkJZHB0eHNldChpdDY1MDUsIDB4NUMsIDB4RjAsIDB4MDApOwo+ICsJCURS TV9ERUJVR19EUklWRVIoIiVzIE9GRiEhXG4iLCBfX2Z1bmNfXyk7Cj4gKwl9Cj4gK30KPiArI2Vu ZGlmCj4gKwo+ICtzdGF0aWMgYm9vbCBkcHR4X2dldHNpbmtocGQoc3RydWN0IGl0NjUwNSAqaXQ2 NTA1KQo+ICt7Cj4gKwl1bnNpZ25lZCBpbnQgdmFsdWU7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXJl dCA9IGRwdHhyZChpdDY1MDUsIDB4MEQsICZ2YWx1ZSk7Cj4gKwo+ICsJaWYgKHJldCA8IDApCj4g KwkJcmV0dXJuIGZhbHNlOwo+ICsKPiArCXJldHVybiAodmFsdWUgJiAyKSA9PSAyOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgdm9pZCBzaG93X3ZpZF9pbmZvKHN0cnVjdCBpdDY1MDUgKml0NjUwNSkKPiAr ewo+ICsJaW50IGhzeW5jX3BvbCwgdnN5bmNfcG9sLCBpbnRlcmxhY2VkOwo+ICsJaW50IGh0b3Rh bCwgaGRlcywgaGRldywgaGZwaCwgaHN5bmN3Owo+ICsJaW50IHZ0b3RhbCwgdmRlcywgdmRldywg dmZwaCwgdnN5bmN3Owo+ICsJaW50IHJkZGF0YSwgcmRkYXRhMSwgaTsKPiArCWludCBwY2xrLCBz dW07Cj4gKwo+ICsJdXNsZWVwX3JhbmdlKDEwMDAwLCAxNTAwMCk7Cj4gKwlkcHR4d3IoaXQ2NTA1 LCAweDBGLCAweDAwKTsKPiArCWRwdHhyZChpdDY1MDUsIDB4YTAsICZyZGRhdGEpOwo+ICsJaHN5 bmNfcG9sID0gcmRkYXRhICYgQklUKDApOwo+ICsJdnN5bmNfcG9sID0gKHJkZGF0YSAmIEJJVCgy KSkgPj4gMjsKPiArCWludGVybGFjZWQgPSAocmRkYXRhICYgQklUKDQpKSA+PiA0Owo+ICsKPiAr CWRwdHhyZChpdDY1MDUsIDB4YTEsICZyZGRhdGEpOwo+ICsJZHB0eHJkKGl0NjUwNSwgMHhhMiwg JnJkZGF0YTEpOwo+ICsJaHRvdGFsID0gKChyZGRhdGExICYgMHgxRikgPDwgOCkgKyByZGRhdGE7 Cj4gKwo+ICsJZHB0eHJkKGl0NjUwNSwgMHhhMywgJnJkZGF0YSk7Cj4gKwlkcHR4cmQoaXQ2NTA1 LCAweGE0LCAmcmRkYXRhMSk7Cj4gKwo+ICsJaGRlcyA9ICgocmRkYXRhMSAmIDB4MUYpIDw8IDgp ICsgcmRkYXRhOwo+ICsKPiArCWRwdHhyZChpdDY1MDUsIDB4YTUsICZyZGRhdGEpOwo+ICsJZHB0 eHJkKGl0NjUwNSwgMHhhNiwgJnJkZGF0YTEpOwo+ICsKPiArCWhkZXcgPSAoKHJkZGF0YTEgJiAw eDFGKSA8PCA4KSArIHJkZGF0YTsKPiArCj4gKwlkcHR4cmQoaXQ2NTA1LCAweGE3LCAmcmRkYXRh KTsKPiArCWRwdHhyZChpdDY1MDUsIDB4YTgsICZyZGRhdGExKTsKPiArCj4gKwloZnBoID0gKChy ZGRhdGExICYgMHgxRikgPDwgOCkgKyByZGRhdGE7Cj4gKwo+ICsJZHB0eHJkKGl0NjUwNSwgMHhh OSwgJnJkZGF0YSk7Cj4gKwlkcHR4cmQoaXQ2NTA1LCAweGFhLCAmcmRkYXRhMSk7Cj4gKwo+ICsJ aHN5bmN3ID0gKChyZGRhdGExICYgMHgxRikgPDwgOCkgKyByZGRhdGE7Cj4gKwo+ICsJZHB0eHJk KGl0NjUwNSwgMHhhYiwgJnJkZGF0YSk7Cj4gKwlkcHR4cmQoaXQ2NTA1LCAweGFjLCAmcmRkYXRh MSk7Cj4gKwl2dG90YWwgPSAoKHJkZGF0YTEgJiAweDBGKSA8PCA4KSArIHJkZGF0YTsKPiArCj4g KwlkcHR4cmQoaXQ2NTA1LCAweGFkLCAmcmRkYXRhKTsKPiArCWRwdHhyZChpdDY1MDUsIDB4YWUs ICZyZGRhdGExKTsKPiArCXZkZXMgPSAoKHJkZGF0YTEgJiAweDBGKSA8PCA4KSArIHJkZGF0YTsK PiArCj4gKwlkcHR4cmQoaXQ2NTA1LCAweGFmLCAmcmRkYXRhKTsKPiArCWRwdHhyZChpdDY1MDUs IDB4YjAsICZyZGRhdGExKTsKPiArCXZkZXcgPSAoKHJkZGF0YTEgJiAweDBGKSA8PCA4KSArIHJk ZGF0YTsKPiArCj4gKwlkcHR4cmQoaXQ2NTA1LCAweGIxLCAmcmRkYXRhKTsKPiArCWRwdHhyZChp dDY1MDUsIDB4YjIsICZyZGRhdGExKTsKPiArCXZmcGggPSAoKHJkZGF0YTEgJiAweDBGKSA8PCA4 KSArIHJkZGF0YTsKPiArCj4gKwlkcHR4cmQoaXQ2NTA1LCAweGIzLCAmcmRkYXRhKTsKPiArCWRw dHhyZChpdDY1MDUsIDB4YjQsICZyZGRhdGExKTsKPiArCXZzeW5jdyA9ICgocmRkYXRhMSAmIDB4 MEYpIDw8IDgpICsgcmRkYXRhOwo+ICsKPiArCXN1bSA9IDA7Cj4gKwlmb3IgKGkgPSAwOyBpIDwg MTAwOyBpKyspIHsKPiArCQlkcHR4c2V0KGl0NjUwNSwgMHgxMiwgMHg4MCwgMHg4MCk7Cj4gKwkJ dXNsZWVwX3JhbmdlKDEwMDAwLCAxNTAwMCk7Cj4gKwkJZHB0eHNldChpdDY1MDUsIDB4MTIsIDB4 ODAsIDB4MDApOwo+ICsKPiArCQlkcHR4cmQoaXQ2NTA1LCAweDEzLCAmcmRkYXRhKTsKPiArCQlk cHR4cmQoaXQ2NTA1LCAweDE0LCAmcmRkYXRhMSk7Cj4gKwkJcmRkYXRhID0gKChyZGRhdGExICYg MHgwRikgPDwgOCkgKyByZGRhdGE7Cj4gKwo+ICsJCXN1bSArPSByZGRhdGE7Cj4gKwl9Cj4gKwo+ ICsJc3VtIC89IDEwMDsKPiArCXBjbGsgPSAxMzUwMCAqIDIwNDggLyBzdW07Cj4gKwo+ICsJRFJN X0RFQlVHX0RSSVZFUigiXG4tLS0tLS0tLS0tVmlkZW8gSW5wdXQgVGltaW5nLS0tLS0tLS0tLVxu Iik7Cj4gKwlEUk1fREVCVUdfRFJJVkVSKCJQQ0xLID0gJWQuJWRNSHpcbiIsIHBjbGsgLyAxMDAw LCBwY2xrICUgMTAwMCk7Cj4gKwlEUk1fREVCVUdfRFJJVkVSKCJIVG90YWwgPSAlZFxuIiwgaHRv dGFsKTsKPiArCURSTV9ERUJVR19EUklWRVIoIkhBY3RpdmUgPSAlZFxuIiwgaGRldyk7Cj4gKwlE Uk1fREVCVUdfRFJJVkVSKCJIRnJvbnRQb3JjaCA9ICVkXG4iLCBoZnBoKTsKPiArCURSTV9ERUJV R19EUklWRVIoIkhTeW5jV2lkdGggPSAlZFxuIiwgaHN5bmN3KTsKPiArCURSTV9ERUJVR19EUklW RVIoIkhCYWNrUG9yY2ggPSAlZFxuIiwgaHRvdGFsIC0gaGRldyAtIGhmcGggLSBoc3luY3cpOwo+ ICsJRFJNX0RFQlVHX0RSSVZFUigiVlRvdGFsID0gJWRcbiIsIHZ0b3RhbCk7Cj4gKwlEUk1fREVC VUdfRFJJVkVSKCJWQWN0aXZlID0gJWRcbiIsIHZkZXcpOwo+ICsJRFJNX0RFQlVHX0RSSVZFUigi VkZyb250UG9yY2ggPSAlZFxuIiwgdmZwaCk7Cj4gKwlEUk1fREVCVUdfRFJJVkVSKCJWU3luY1dp ZHRoID0gJWRcbiIsIHZzeW5jdyk7Cj4gKwlEUk1fREVCVUdfRFJJVkVSKCJWQmFja1BvcmNoID0g JWRcbiIsIHZ0b3RhbCAtIHZkZXcgLSB2ZnBoIC0gdnN5bmN3KTsKCkNhbiBEUk1fTU9ERV9GTVQg YW5kIERSTV9NT0RFX0FSRyBiZSB1c2VkIGhlcmU/Cgo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBk cHR4X3N5c19jaGcoc3RydWN0IGl0NjUwNSAqaXQ2NTA1LCBlbnVtIHN5c19zdGF0dXMgbmV3c3Rh dGUpCj4gK3sKPiArCXVuc2lnbmVkIGludCBpID0gMDsKPiArCXVuc2lnbmVkIGludCByZWcwNiwg cmVnMDcsIHJlZzA4LCByZWcwZCwgcmVnMGU7Cj4gKwo+ICsJZHB0eHJkKGl0NjUwNSwgMHgwNiwg JnJlZzA2KTsKPiArCWRwdHhyZChpdDY1MDUsIDB4MDcsICZyZWcwNyk7Cj4gKwlkcHR4cmQoaXQ2 NTA1LCAweDA4LCAmcmVnMDgpOwo+ICsJZHB0eHJkKGl0NjUwNSwgMHgwZCwgJnJlZzBkKTsKPiAr CWRwdHhyZChpdDY1MDUsIDB4MGUsICZyZWcwZSk7Cj4gKwo+ICsJRFJNX0RFQlVHX0RSSVZFUigi WyVzXXJlZzA2ID0gMHgleFxuIiwgX19mdW5jX18sIHJlZzA2KTsKPiArCURSTV9ERUJVR19EUklW RVIoIlslc11yZWcwNyA9IDB4JXhcbiIsIF9fZnVuY19fLCByZWcwNyk7Cj4gKwlEUk1fREVCVUdf RFJJVkVSKCJbJXNdcmVnMDggPSAweCV4XG4iLCBfX2Z1bmNfXywgcmVnMDgpOwo+ICsJRFJNX0RF QlVHX0RSSVZFUigiWyVzXXJlZzBkID0gMHgleFxuIiwgX19mdW5jX18sIHJlZzBkKTsKPiArCURS TV9ERUJVR19EUklWRVIoIlslc11yZWcwZSA9IDB4JXhcbiIsIF9fZnVuY19fLCByZWcwZSk7Ckxv b2tzIGxpa2UgZGVidWdnaW5nIGFydGlmYWN0cyB0aGF0IGFyZSBub3QgcmVsZXZhbnQgaW4gYSBw cm9kdWN0aW9uCmRyaXZlci4KCj4gKwo+ICsJaWYgKG5ld3N0YXRlICE9IFNZU19VTlBMVUcpIHsK PiArCQlpZiAoIWRwdHhfZ2V0c2lua2hwZChpdDY1MDUpKQo+ICsJCQluZXdzdGF0ZSA9IFNZU19V TlBMVUc7Cj4gKwl9Cj4gKwo+ICsJaXQ2NTA1LT5zdGF0dXMgPSBuZXdzdGF0ZTsKPiArCj4gKwlz d2l0Y2ggKGl0NjUwNS0+c3RhdHVzKSB7Cj4gKwljYXNlIFNZU19VTlBMVUc6Cj4gKwkJRFJNX0RF QlVHX0RSSVZFUigic3lzX3N0YXRlIGlzIGNoYW5naW5nIHRvIFNZU19VTlBMVUchIik7Cj4gKwkJ a2ZyZWUoaXQ2NTA1LT5lZGlkKTsKPiArCQlpdDY1MDUtPmVkaWQgPSBOVUxMOwo+ICsJCURSTV9E RUJVR19EUklWRVIoIkZyZWUgaXQ2NTA1IEVESUQgbWVtb3J5ISIpOwo+ICsjaWYgKENISVBfVkVS U0lPTiA9PSBCWCkKPiArCQlpdDY1MDVfdGVybWluYXRpb24oaXQ2NTA1LCBmYWxzZSk7Cj4gKyNl bmRpZgo+ICsJCWJyZWFrOwo+ICsJY2FzZSBTWVNfSFBEOgo+ICsJCURSTV9ERUJVR19EUklWRVIo InN5c19zdGF0ZSBpcyBjaGFuZ2luZyB0byBTWVNfSFBEISIpOwo+ICsjaWYgKENISVBfVkVSU0lP TiA9PSBCWCkKPiArCQlpdDY1MDVfdGVybWluYXRpb24oaXQ2NTA1LCB0cnVlKTsKPiArI2VuZGlm Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIFNZU19BVVRPVFJBSU46Cj4gKwkJRFJNX0RFQlVHX0RSSVZF Uigic3lzX3N0YXRlIGlzIGNoYW5naW5nIHRvIFNZU19BVVRPVFJBSU4hIik7Cj4gKwkJYnJlYWs7 Cj4gKwljYXNlIFNZU19XQUlUOgo+ICsJCURSTV9ERUJVR19EUklWRVIoInN5c19zdGF0ZSBpcyBj aGFuZ2luZyB0byBTWVNfV0FJVCEiKTsKPiArCQlicmVhazsKPiArI2lmZGVmIENPTkZJR19EUk1f SVRFX0lUNjUwNV9FTkhEQ1AKPiArCWNhc2UgU1lTX1JlSERDUDoKPiArCQlEUk1fREVCVUdfRFJJ VkVSKCJzeXNfc3RhdGUgaXMgY2hhbmdpbmcgdG8gU1lTX1JlSERDUCEiKTsKPiArCQlicmVhazsK PiArI2VuZGlmCj4gKwljYXNlIFNZU19OT1JPUDoKPiArCQlEUk1fREVCVUdfRFJJVkVSKCJzeXNf c3RhdGUgaXMgY2hhbmdpbmcgdG8gU1lTX05PUk9QISIpOwo+ICsJCWZvciAoaSA9IDA7IGkgPCBT SE9XVklERU9USU1JTkc7IGkrKykKPiArCQkJc2hvd192aWRfaW5mbyhpdDY1MDUpOwo+ICsjaWZk ZWYgVEVTVF9NT0RFCj4gKwkJaXQ2NTA1LT5pdDY1MDVfZHJ2X2hvbGQgPSAxOwo+ICsJCURSTV9E RUJVR19EUklWRVIoInNldCBpdDY1MDVfZHJ2X2hvbGQ6JWQiLAo+ICsJCQkJaXQ2NTA1LT5pdDY1 MDVfZHJ2X2hvbGQpOwo+ICsjZW5kaWYKPiArCQlicmVhazsKPiArCWNhc2UgU1lTX1BXUkROOgo+ ICsJCURSTV9ERUJVR19EUklWRVIoInN5c19zdGF0ZSBpcyBjaGFuZ2luZyB0byBTWVNfUFdSRE4h Iik7Cj4gKwkJLyogUmVzZXQgYW5kIFB3ckRuIEFGRSAqLwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVs dDoKPiArCQlEUk1fREVCVUdfRFJJVkVSKCJzeXNfc3RhdGUgaXMgY2hhbmdpbmcgdG8gU1lTX1VO S05PV04hIik7Cj4gKwkJYnJlYWs7Cj4gKwl9Cj4gK30KCkkgYnJvd3NlZCB0aGUgZHJpdmVyIGFu ZCBkaWQgbm90IGZpbmQgYW55dGhpbmcgb3RoZXIKdGhhbiBpc3N1ZXMgdGhhdCBhcmUgYWxyZWFk eSByZXBvcnRlZCBhYm92ZS4KCkFzIEkgaGF2ZSBubyBleHBlcmllbmNlIHdpdGggYSBicmlkZ2Ug ZHJpdmVyIGFzIHN1Y2ggdGhlIGZ1bmN0aW9uYWxpdHkKd2FzIG5vdCBsb29rZWQgYXQuCgoJU2Ft Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZl bCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xp c3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbA== 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=-8.4 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,T_DKIMWL_WL_HIGH,URIBL_BLOCKED,USER_AGENT_MUTT 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 29810C04A6B for ; Wed, 8 May 2019 21:07:56 +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 E63982173B for ; Wed, 8 May 2019 21:07:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="S0O+qf8r" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E63982173B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ravnborg.org 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:In-Reply-To:MIME-Version:References: Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Wc7/gFhJic1/dnAzR7xbBmAjQ8sbhFT1r8Vh/V5R19E=; b=S0O+qf8rAiy9xh nzSkhs3fP14dDXjancU1bvBuIMk2vg34nawPMvzCv8oYX0K8oGMcZG88DFexht4/IeSZXuvV9Txfi LwnFxj/X5MxCF+1t94ogMBL+l95o7m7eV1eml39YgAXPrJvVaUNnpaqST32KENYCYBPflIFojVnNC WQiuSDQe3Fsn74/PlwnrH8SP0TpQ4ooZhX5qQ1LBo/Ks6ZMCM9fL4noMcrGc4XP+H5/jQDHYKpsCs c1zXtQrJteXhp4ZjKM3Lt1BK197BM8YwiW2WLBksyF6hsXhTiOOlp/+H4qO/oLc/isCCDqKl4SASl yQzWwHWJ5l1j3rvZJpDA==; 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 1hOTn4-0005xi-MP; Wed, 08 May 2019 21:07:50 +0000 Received: from asavdk3.altibox.net ([109.247.116.14]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hOTmz-0005wC-Rb; Wed, 08 May 2019 21:07:48 +0000 Received: from ravnborg.org (unknown [158.248.194.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by asavdk3.altibox.net (Postfix) with ESMTPS id F0EBF2002D; Wed, 8 May 2019 23:07:32 +0200 (CEST) Date: Wed, 8 May 2019 23:07:31 +0200 From: Sam Ravnborg To: allen Subject: Re: [PATCH 2/3] drm/bridge: add it6505 driver Message-ID: <20190508210731.GA19781@ravnborg.org> References: <1557301722-20827-1-git-send-email-allen.chen@ite.com.tw> <1557301722-20827-3-git-send-email-allen.chen@ite.com.tw> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1557301722-20827-3-git-send-email-allen.chen@ite.com.tw> User-Agent: Mutt/1.10.1 (2018-07-13) X-CMAE-Score: 0 X-CMAE-Analysis: v=2.3 cv=dqr19Wo4 c=1 sm=1 tr=0 a=UWs3HLbX/2nnQ3s7vZ42gw==:117 a=UWs3HLbX/2nnQ3s7vZ42gw==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=Ns9eNvu6AAAA:8 a=mpaa-ttXAAAA:8 a=1XWaLZrsAAAA:8 a=-sMfrFBIwg32JD2js3EA:9 a=nplNrf5OaxeiL364:21 a=b2S3cVGQPHHqZ59X:21 a=CjuIK1q_8ugA:10 a=LZLx1i01EnjtqRv10NxV:22 a=6heAxKwa5pAsJatQ0mat:22 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190508_140746_451197_50C5C3FB X-CRM114-Status: GOOD ( 29.81 ) 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: Archit Taneja , Jitao Shi , Yilun Lin , open list , "open list:DRM DRIVERS" , David Airlie , "moderated list:ARM/Mediatek SoC support" , Laurent Pinchart , Pi-Hsun Shih , Matthias Brugger , "moderated list:ARM/Mediatek SoC support" 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 Hi allen. Thanks for this fine patch. A few comments follows. Consider to use DRM_DEV_ERROR and friends. Then you get the devicename included in logging and this makes it much easier to find relevant entries. On Wed, May 08, 2019 at 03:48:41PM +0800, allen wrote: > From: Allen Chen > > This adds support for the iTE IT6505. > This device can convert DPI signal to DP output. > > Signed-off-by: Jitao Shi > Signed-off-by: Yilun Lin > Signed-off-by: Allen Chen > --- > drivers/gpu/drm/bridge/Kconfig | 22 + > drivers/gpu/drm/bridge/Makefile | 1 + > drivers/gpu/drm/bridge/ite-it6505.c | 2637 +++++++++++++++++++++++++++++++++++ > 3 files changed, 2660 insertions(+) > create mode 100644 drivers/gpu/drm/bridge/ite-it6505.c > > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig > index 9c9c4df..d12e48c 100644 > --- a/drivers/gpu/drm/bridge/Kconfig > +++ b/drivers/gpu/drm/bridge/Kconfig > @@ -43,6 +43,28 @@ config DRM_DUMB_VGA_DAC > Support for non-programmable RGB to VGA DAC bridges, such as ADI > ADV7123, TI THS8134 and THS8135 or passive resistor ladder DACs. > > +config DRM_ITE_IT6505 > + tristate "ITE IT6505 DP bridge" > + depends on OF > + select DRM_KMS_HELPER > + help > + ITE IT6505 DP bridge chip driver. Why is it relevant to have these features as features that can be enabed/disabled on Kconfig level? It is likely more flexible to do it run-time if needed to turn them off. And it would simplify the code. > + > +config DRM_ITE_IT6505_ENHDCP > + tristate "Enable IT6505 HDCP function" > + depends on DRM_ITE_IT6505 > + default y > + > +config DRM_ITE_IT6505_ENAUD > + tristate "Enable IT6505 audio function" > + depends on DRM_ITE_IT6505 > + default y > + > +config DRM_ITE_IT6505_ENPWRONOFF > + tristate "Enable IT6505 power on/off function" > + depends on DRM_ITE_IT6505 > + default y > + > config DRM_LVDS_ENCODER > tristate "Transparent parallel to LVDS encoder support" > depends on OF > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile > index 4934fcf..f5abca5 100644 > --- a/drivers/gpu/drm/bridge/Makefile > +++ b/drivers/gpu/drm/bridge/Makefile > @@ -2,6 +2,7 @@ > obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o > obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o > obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o > +obj-$(CONFIG_DRM_ITE_IT6505) += ite-it6505.o > obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o > obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o > obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o > diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c > new file mode 100644 > index 0000000..13079a8 > --- /dev/null > +++ b/drivers/gpu/drm/bridge/ite-it6505.c > @@ -0,0 +1,2637 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) 2018, The Linux Foundation. All rights reserved. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include Please put a blank line between the individual blocks of include files. So all #include + > +#define AX 0 > +#define BX 1 > +#define AUDSEL I2S > +#define AUDTYPE LPCM > +#define AUDFS AUD48K > +#define AUDCH 2 > +/* 0: Standard I2S;1: 32bit I2S */ > +#define I2SINPUTFMT 1 > +/* 0: Left-justified;1: Right-justified */ > +#define I2SJUSTIFIED 0 > +/* 0: Data delay 1T correspond to WS;1: No data delay correspond to WS */ > +#define I2SDATADELAY 0 > +/* 0: is left channel;1: is right channel */ > +#define I2SWSCHANNEL 0 > +/* 0: MSB shift first;1: LSB shift first */ > +#define I2SDATASEQ 0 > + > +#define LANESWAP 0 > +#define LANE 4 > +#define _HBR 1 > +#define ENHFRAME 1 > +#define ENSSC 1 > + > +#define FLAGTRAINDOWN 100 > +#define TRAINFAILCNT 5 > +#define AUX_WAIT_TIMEOUT_MS 15 > +#define PCLK_DELAY 1 > +#define PCLK_INV 0 > +#define EDIDRETRYTIME 5 > +#define SHOWVIDEOTIMING 2 > +#define PWROFFRETRYTIME 5 > + > +/* AX or BX */ > +#define CHIP_VERSION BX If this driver is for BX only then drop the AX releated code. This would simplify the driver. If this is really needed then provide an empty variant of it6505_termination() for AX, to simplify the call sites. And it6505_termination() calls for two functions so we void a bool parameter that makes the function do two different things. > + > +/* if use this define will power on in probe */ > +/* #define TEST_MODE */ > + > +/* if use this define will enable AUX debug option */ > +/* #define ENAUX_TRANSFER_DEBUG */ > + > +/* if use this define will enable SHA debug */ > +/* #define SHA_DEBUG */ Consider how much of this really belongs in a production driver. If relevant consider to add some way to enable this runtime. > + > +enum sys_status { > + SYS_UNPLUG = 0, > + SYS_HPD, > + SYS_AUTOTRAIN, > + SYS_WAIT, > + SYS_TRAINFAIL, > + SYS_ReHDCP, > + SYS_PWRDN, > + SYS_NOROP, > + SYS_Unknown, > +}; > + > +enum it6505_aud_sel { > + I2S = 0, > + SPDIF, > +}; > + > +enum it6505_aud_fs { > + AUD24K = 0x6, > + AUD32K = 0x3, > + AUD48K = 0x2, > + AUD96K = 0xA, > + AUD192K = 0xE, > + AUD44P1K = 0x0, > + AUD88P2K = 0x8, > + AUD176P4K = 0xC, > +}; > + > +enum it6505_aud_type { > + LPCM = 0, > + NLPCM, > + DSS, > + HBR, > +}; > + > +enum aud_word_length { > + AUD16BIT = 0, > + AUD18BIT, > + AUD20BIT, > + AUD24BIT, > +}; > + > +/* Audio Sample Word Length: AUD16BIT, AUD18BIT, AUD20BIT, AUD24BIT */ > +#define AUDWORDLENGTH AUD24BIT > + > +struct it6505_platform_data { > + struct regulator *pwr18; > + struct regulator *ovdd; > + struct gpio_desc *gpiod_hpd; > + struct gpio_desc *gpiod_pd; gpiod_pd is not used and can be deleted. > + struct gpio_desc *gpiod_reset; > + > + int hpd_irq; > + int intp_irq; hpd_irq and intp_irq are only used in one function. Drop them from it6505_platform_data and use local variables. > +}; > + > +struct it6505_dp_port { > + struct it6505 *it6505_dp; > + struct notifier_block event_nb; > + struct extcon_dev *extcon; > + struct work_struct extcon_wq; > + u8 id; It did not see this used, only assigned. Maybe I missed something? > +}; > + > +struct it6505 { > + struct drm_dp_aux aux; > + struct drm_bridge bridge; > + struct i2c_client *client; > + struct edid *edid; > + struct drm_connector connector; > + struct drm_dp_link link; > + struct it6505_platform_data pdata; > + struct mutex lock; I would be helpfull with a comment what the lock protects. > + struct regmap *regmap; > + struct it6505_dp_port *port; > + /* thread sequence control */ > + struct semaphore sem_notifier; > + > + u8 dpcd[DP_RECEIVER_CAP_SIZE]; > + enum sys_status status; > + u8 dumpdpcd[30]; > + u8 dpcd_rev; dpcd_rev is only used in one function. Drop it and use local variabel. I did not check further - please verify that all members are used and are relevant to have in this struct. > + bool hbr; > + u8 lane; > + u8 en_ssc; > + bool en_hframe; > + bool laneswap; > + > + enum it6505_aud_sel aud_sel; > + enum it6505_aud_fs aud_fs; > + enum it6505_aud_type aud_type; > + u8 aud_ch; > + u8 i2s_input_fmt; > + u8 i2s_justified; > + u8 i2s_data_delay; > + u8 i2s_ws_channel; > + u8 i2s_data_seq; > + u8 vidstable_done; > + enum aud_word_length audwordlength; > + u8 cntfsm; > + bool cp_ready; > + unsigned int bstatus; > + bool cp_done; > + u8 downstream_repeater; > + u8 am0[8]; > + u8 binfo[2]; > + u8 ksvlist[5 * 12]; > + unsigned int sha[5]; > + unsigned int w[80]; > + u8 shainput[64]; > + u8 av[5][4]; > + u8 bv[5][4]; > + u8 passsha; > + bool powered; > + /* it6505 driver hold option */ > + unsigned int it6505_drv_hold; > +}; > + > +static int it6505_poweron(struct it6505 *it6505); > +#ifdef CONFIG_DRM_ITE_IT6505_ENPWRONOFF > +static int it6505_poweroff(struct it6505 *it6505); > +#endif > + > +static const struct regmap_range it6505_bridge_volatile_ranges[] = { > + { .range_min = 0, .range_max = 0xFF }, > +}; > + > +static const struct regmap_access_table it6505_bridge_volatile_table = { > + .yes_ranges = it6505_bridge_volatile_ranges, > + .n_yes_ranges = ARRAY_SIZE(it6505_bridge_volatile_ranges), > +}; > + > +static const struct regmap_config it6505_bridge_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > + .volatile_table = &it6505_bridge_volatile_table, > + .cache_type = REGCACHE_NONE, > +}; > + > +static int dptxrd(struct it6505 *it6505, unsigned int reg_addr, > + unsigned int *value) > +{ > + int err; > + > + err = regmap_read(it6505->regmap, reg_addr, value); > + if (err < 0) { > + DRM_ERROR("%s read fail err reg_addr[0x%x] err:%d\n", > + __func__, reg_addr, err); > + return err; > + } > + > + return 0; > +} > + > +static void it6505_dump(struct it6505 *it6505) > +{ > + unsigned int value, i; > + > + DRM_DEBUG_DRIVER("\n----------%s start----------\n", __func__); > + for (i = 0; i <= 0xff; i++) { > + dptxrd(it6505, i, &value); > + DRM_DEBUG_DRIVER("%s[0x%x] = 0x%x\n", __func__, i, value); > + } > + DRM_DEBUG_DRIVER("\n----------%s end----------\n\n", __func__); > +} Are these headers really needed in a production driver? > + > +static int dptxwr(struct it6505 *it6505, unsigned int reg_addr, > + unsigned int reg_val) > +{ > + int err; > + > + err = regmap_write(it6505->regmap, reg_addr, reg_val); > + > + if (err < 0) { > + DRM_ERROR("%s write fail err reg[0x%x] = 0x%x err = %d\n", > + __func__, reg_addr, reg_val, err); > + return err; > + } > + > + return 0; > +} > + > +static int dptxset(struct it6505 *it6505, unsigned int reg, unsigned int mask, > + unsigned int value) > +{ > + int err; > + > + err = regmap_update_bits(it6505->regmap, reg, mask, value); > + if (err < 0) { > + DRM_ERROR("%s write fail err %d\n", __func__, err); > + return err; > + } > + > + return 0; > +} > + > +static inline struct it6505 *connector_to_it6505(struct drm_connector *c) > +{ > + return container_of(c, struct it6505, connector); > +} > + > +static inline struct it6505 *bridge_to_it6505(struct drm_bridge *bridge) > +{ > + return container_of(bridge, struct it6505, bridge); > +} > + > +static void it6505_init_fsm(struct it6505 *it6505) > +{ > + it6505->aud_sel = AUDSEL; > + it6505->aud_fs = AUDFS; > + it6505->aud_ch = AUDCH; > + it6505->aud_type = AUDTYPE; > + it6505->i2s_input_fmt = I2SINPUTFMT; > + it6505->i2s_justified = I2SJUSTIFIED; > + it6505->i2s_data_delay = I2SDATADELAY; > + it6505->i2s_ws_channel = I2SWSCHANNEL; > + it6505->i2s_data_seq = I2SDATASEQ; > + it6505->audwordlength = AUDWORDLENGTH; > + > + it6505->status = SYS_Unknown; > + it6505->hbr = _HBR; > + it6505->lane = LANE; > + it6505->en_ssc = ENSSC; > + it6505->en_hframe = ENHFRAME; > + it6505->laneswap = LANESWAP; > + it6505->vidstable_done = 0; > +} > + > +#if (CHIP_VERSION == BX) > +static void it6505_termination(struct it6505 *it6505, bool s) > +{ > + DRM_DEBUG_DRIVER("%s switch!!\n", __func__); > + if (s) { > + dptxset(it6505, 0x5D, 0x80, 0x00); > + dptxset(it6505, 0x5E, 0x02, 0x02); > + DRM_DEBUG_DRIVER("%s ON!!\n", __func__); > + } else { > + dptxset(it6505, 0x5D, 0x80, 0x80); > + dptxset(it6505, 0x5E, 0x02, 0x00); > + dptxset(it6505, 0x5C, 0xF0, 0x00); > + DRM_DEBUG_DRIVER("%s OFF!!\n", __func__); > + } > +} > +#endif > + > +static bool dptx_getsinkhpd(struct it6505 *it6505) > +{ > + unsigned int value; > + int ret; > + > + ret = dptxrd(it6505, 0x0D, &value); > + > + if (ret < 0) > + return false; > + > + return (value & 2) == 2; > +} > + > +static void show_vid_info(struct it6505 *it6505) > +{ > + int hsync_pol, vsync_pol, interlaced; > + int htotal, hdes, hdew, hfph, hsyncw; > + int vtotal, vdes, vdew, vfph, vsyncw; > + int rddata, rddata1, i; > + int pclk, sum; > + > + usleep_range(10000, 15000); > + dptxwr(it6505, 0x0F, 0x00); > + dptxrd(it6505, 0xa0, &rddata); > + hsync_pol = rddata & BIT(0); > + vsync_pol = (rddata & BIT(2)) >> 2; > + interlaced = (rddata & BIT(4)) >> 4; > + > + dptxrd(it6505, 0xa1, &rddata); > + dptxrd(it6505, 0xa2, &rddata1); > + htotal = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xa3, &rddata); > + dptxrd(it6505, 0xa4, &rddata1); > + > + hdes = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xa5, &rddata); > + dptxrd(it6505, 0xa6, &rddata1); > + > + hdew = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xa7, &rddata); > + dptxrd(it6505, 0xa8, &rddata1); > + > + hfph = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xa9, &rddata); > + dptxrd(it6505, 0xaa, &rddata1); > + > + hsyncw = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xab, &rddata); > + dptxrd(it6505, 0xac, &rddata1); > + vtotal = ((rddata1 & 0x0F) << 8) + rddata; > + > + dptxrd(it6505, 0xad, &rddata); > + dptxrd(it6505, 0xae, &rddata1); > + vdes = ((rddata1 & 0x0F) << 8) + rddata; > + > + dptxrd(it6505, 0xaf, &rddata); > + dptxrd(it6505, 0xb0, &rddata1); > + vdew = ((rddata1 & 0x0F) << 8) + rddata; > + > + dptxrd(it6505, 0xb1, &rddata); > + dptxrd(it6505, 0xb2, &rddata1); > + vfph = ((rddata1 & 0x0F) << 8) + rddata; > + > + dptxrd(it6505, 0xb3, &rddata); > + dptxrd(it6505, 0xb4, &rddata1); > + vsyncw = ((rddata1 & 0x0F) << 8) + rddata; > + > + sum = 0; > + for (i = 0; i < 100; i++) { > + dptxset(it6505, 0x12, 0x80, 0x80); > + usleep_range(10000, 15000); > + dptxset(it6505, 0x12, 0x80, 0x00); > + > + dptxrd(it6505, 0x13, &rddata); > + dptxrd(it6505, 0x14, &rddata1); > + rddata = ((rddata1 & 0x0F) << 8) + rddata; > + > + sum += rddata; > + } > + > + sum /= 100; > + pclk = 13500 * 2048 / sum; > + > + DRM_DEBUG_DRIVER("\n----------Video Input Timing----------\n"); > + DRM_DEBUG_DRIVER("PCLK = %d.%dMHz\n", pclk / 1000, pclk % 1000); > + DRM_DEBUG_DRIVER("HTotal = %d\n", htotal); > + DRM_DEBUG_DRIVER("HActive = %d\n", hdew); > + DRM_DEBUG_DRIVER("HFrontPorch = %d\n", hfph); > + DRM_DEBUG_DRIVER("HSyncWidth = %d\n", hsyncw); > + DRM_DEBUG_DRIVER("HBackPorch = %d\n", htotal - hdew - hfph - hsyncw); > + DRM_DEBUG_DRIVER("VTotal = %d\n", vtotal); > + DRM_DEBUG_DRIVER("VActive = %d\n", vdew); > + DRM_DEBUG_DRIVER("VFrontPorch = %d\n", vfph); > + DRM_DEBUG_DRIVER("VSyncWidth = %d\n", vsyncw); > + DRM_DEBUG_DRIVER("VBackPorch = %d\n", vtotal - vdew - vfph - vsyncw); Can DRM_MODE_FMT and DRM_MODE_ARG be used here? > +} > + > +static void dptx_sys_chg(struct it6505 *it6505, enum sys_status newstate) > +{ > + unsigned int i = 0; > + unsigned int reg06, reg07, reg08, reg0d, reg0e; > + > + dptxrd(it6505, 0x06, ®06); > + dptxrd(it6505, 0x07, ®07); > + dptxrd(it6505, 0x08, ®08); > + dptxrd(it6505, 0x0d, ®0d); > + dptxrd(it6505, 0x0e, ®0e); > + > + DRM_DEBUG_DRIVER("[%s]reg06 = 0x%x\n", __func__, reg06); > + DRM_DEBUG_DRIVER("[%s]reg07 = 0x%x\n", __func__, reg07); > + DRM_DEBUG_DRIVER("[%s]reg08 = 0x%x\n", __func__, reg08); > + DRM_DEBUG_DRIVER("[%s]reg0d = 0x%x\n", __func__, reg0d); > + DRM_DEBUG_DRIVER("[%s]reg0e = 0x%x\n", __func__, reg0e); Looks like debugging artifacts that are not relevant in a production driver. > + > + if (newstate != SYS_UNPLUG) { > + if (!dptx_getsinkhpd(it6505)) > + newstate = SYS_UNPLUG; > + } > + > + it6505->status = newstate; > + > + switch (it6505->status) { > + case SYS_UNPLUG: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_UNPLUG!"); > + kfree(it6505->edid); > + it6505->edid = NULL; > + DRM_DEBUG_DRIVER("Free it6505 EDID memory!"); > +#if (CHIP_VERSION == BX) > + it6505_termination(it6505, false); > +#endif > + break; > + case SYS_HPD: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_HPD!"); > +#if (CHIP_VERSION == BX) > + it6505_termination(it6505, true); > +#endif > + break; > + case SYS_AUTOTRAIN: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_AUTOTRAIN!"); > + break; > + case SYS_WAIT: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_WAIT!"); > + break; > +#ifdef CONFIG_DRM_ITE_IT6505_ENHDCP > + case SYS_ReHDCP: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_ReHDCP!"); > + break; > +#endif > + case SYS_NOROP: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_NOROP!"); > + for (i = 0; i < SHOWVIDEOTIMING; i++) > + show_vid_info(it6505); > +#ifdef TEST_MODE > + it6505->it6505_drv_hold = 1; > + DRM_DEBUG_DRIVER("set it6505_drv_hold:%d", > + it6505->it6505_drv_hold); > +#endif > + break; > + case SYS_PWRDN: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_PWRDN!"); > + /* Reset and PwrDn AFE */ > + break; > + default: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_UNKNOWN!"); > + break; > + } > +} I browsed the driver and did not find anything other than issues that are already reported above. As I have no experience with a bridge driver as such the functionality was not looked at. Sam _______________________________________________ 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=-8.4 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED, USER_AGENT_MUTT 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 88949C04A6B for ; Wed, 8 May 2019 21:07:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4857420989 for ; Wed, 8 May 2019 21:07:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727488AbfEHVHm (ORCPT ); Wed, 8 May 2019 17:07:42 -0400 Received: from asavdk3.altibox.net ([109.247.116.14]:36379 "EHLO asavdk3.altibox.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726836AbfEHVHl (ORCPT ); Wed, 8 May 2019 17:07:41 -0400 Received: from ravnborg.org (unknown [158.248.194.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by asavdk3.altibox.net (Postfix) with ESMTPS id F0EBF2002D; Wed, 8 May 2019 23:07:32 +0200 (CEST) Date: Wed, 8 May 2019 23:07:31 +0200 From: Sam Ravnborg To: allen Cc: Archit Taneja , Jitao Shi , Yilun Lin , David Airlie , open list , "open list:DRM DRIVERS" , "moderated list:ARM/Mediatek SoC support" , Laurent Pinchart , Pi-Hsun Shih , Matthias Brugger , "moderated list:ARM/Mediatek SoC support" Subject: Re: [PATCH 2/3] drm/bridge: add it6505 driver Message-ID: <20190508210731.GA19781@ravnborg.org> References: <1557301722-20827-1-git-send-email-allen.chen@ite.com.tw> <1557301722-20827-3-git-send-email-allen.chen@ite.com.tw> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1557301722-20827-3-git-send-email-allen.chen@ite.com.tw> User-Agent: Mutt/1.10.1 (2018-07-13) X-CMAE-Score: 0 X-CMAE-Analysis: v=2.3 cv=dqr19Wo4 c=1 sm=1 tr=0 a=UWs3HLbX/2nnQ3s7vZ42gw==:117 a=UWs3HLbX/2nnQ3s7vZ42gw==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=Ns9eNvu6AAAA:8 a=mpaa-ttXAAAA:8 a=1XWaLZrsAAAA:8 a=-sMfrFBIwg32JD2js3EA:9 a=nplNrf5OaxeiL364:21 a=b2S3cVGQPHHqZ59X:21 a=CjuIK1q_8ugA:10 a=LZLx1i01EnjtqRv10NxV:22 a=6heAxKwa5pAsJatQ0mat:22 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi allen. Thanks for this fine patch. A few comments follows. Consider to use DRM_DEV_ERROR and friends. Then you get the devicename included in logging and this makes it much easier to find relevant entries. On Wed, May 08, 2019 at 03:48:41PM +0800, allen wrote: > From: Allen Chen > > This adds support for the iTE IT6505. > This device can convert DPI signal to DP output. > > Signed-off-by: Jitao Shi > Signed-off-by: Yilun Lin > Signed-off-by: Allen Chen > --- > drivers/gpu/drm/bridge/Kconfig | 22 + > drivers/gpu/drm/bridge/Makefile | 1 + > drivers/gpu/drm/bridge/ite-it6505.c | 2637 +++++++++++++++++++++++++++++++++++ > 3 files changed, 2660 insertions(+) > create mode 100644 drivers/gpu/drm/bridge/ite-it6505.c > > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig > index 9c9c4df..d12e48c 100644 > --- a/drivers/gpu/drm/bridge/Kconfig > +++ b/drivers/gpu/drm/bridge/Kconfig > @@ -43,6 +43,28 @@ config DRM_DUMB_VGA_DAC > Support for non-programmable RGB to VGA DAC bridges, such as ADI > ADV7123, TI THS8134 and THS8135 or passive resistor ladder DACs. > > +config DRM_ITE_IT6505 > + tristate "ITE IT6505 DP bridge" > + depends on OF > + select DRM_KMS_HELPER > + help > + ITE IT6505 DP bridge chip driver. Why is it relevant to have these features as features that can be enabed/disabled on Kconfig level? It is likely more flexible to do it run-time if needed to turn them off. And it would simplify the code. > + > +config DRM_ITE_IT6505_ENHDCP > + tristate "Enable IT6505 HDCP function" > + depends on DRM_ITE_IT6505 > + default y > + > +config DRM_ITE_IT6505_ENAUD > + tristate "Enable IT6505 audio function" > + depends on DRM_ITE_IT6505 > + default y > + > +config DRM_ITE_IT6505_ENPWRONOFF > + tristate "Enable IT6505 power on/off function" > + depends on DRM_ITE_IT6505 > + default y > + > config DRM_LVDS_ENCODER > tristate "Transparent parallel to LVDS encoder support" > depends on OF > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile > index 4934fcf..f5abca5 100644 > --- a/drivers/gpu/drm/bridge/Makefile > +++ b/drivers/gpu/drm/bridge/Makefile > @@ -2,6 +2,7 @@ > obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o > obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o > obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o > +obj-$(CONFIG_DRM_ITE_IT6505) += ite-it6505.o > obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o > obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o > obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o > diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c > new file mode 100644 > index 0000000..13079a8 > --- /dev/null > +++ b/drivers/gpu/drm/bridge/ite-it6505.c > @@ -0,0 +1,2637 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) 2018, The Linux Foundation. All rights reserved. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include Please put a blank line between the individual blocks of include files. So all #include + > +#define AX 0 > +#define BX 1 > +#define AUDSEL I2S > +#define AUDTYPE LPCM > +#define AUDFS AUD48K > +#define AUDCH 2 > +/* 0: Standard I2S;1: 32bit I2S */ > +#define I2SINPUTFMT 1 > +/* 0: Left-justified;1: Right-justified */ > +#define I2SJUSTIFIED 0 > +/* 0: Data delay 1T correspond to WS;1: No data delay correspond to WS */ > +#define I2SDATADELAY 0 > +/* 0: is left channel;1: is right channel */ > +#define I2SWSCHANNEL 0 > +/* 0: MSB shift first;1: LSB shift first */ > +#define I2SDATASEQ 0 > + > +#define LANESWAP 0 > +#define LANE 4 > +#define _HBR 1 > +#define ENHFRAME 1 > +#define ENSSC 1 > + > +#define FLAGTRAINDOWN 100 > +#define TRAINFAILCNT 5 > +#define AUX_WAIT_TIMEOUT_MS 15 > +#define PCLK_DELAY 1 > +#define PCLK_INV 0 > +#define EDIDRETRYTIME 5 > +#define SHOWVIDEOTIMING 2 > +#define PWROFFRETRYTIME 5 > + > +/* AX or BX */ > +#define CHIP_VERSION BX If this driver is for BX only then drop the AX releated code. This would simplify the driver. If this is really needed then provide an empty variant of it6505_termination() for AX, to simplify the call sites. And it6505_termination() calls for two functions so we void a bool parameter that makes the function do two different things. > + > +/* if use this define will power on in probe */ > +/* #define TEST_MODE */ > + > +/* if use this define will enable AUX debug option */ > +/* #define ENAUX_TRANSFER_DEBUG */ > + > +/* if use this define will enable SHA debug */ > +/* #define SHA_DEBUG */ Consider how much of this really belongs in a production driver. If relevant consider to add some way to enable this runtime. > + > +enum sys_status { > + SYS_UNPLUG = 0, > + SYS_HPD, > + SYS_AUTOTRAIN, > + SYS_WAIT, > + SYS_TRAINFAIL, > + SYS_ReHDCP, > + SYS_PWRDN, > + SYS_NOROP, > + SYS_Unknown, > +}; > + > +enum it6505_aud_sel { > + I2S = 0, > + SPDIF, > +}; > + > +enum it6505_aud_fs { > + AUD24K = 0x6, > + AUD32K = 0x3, > + AUD48K = 0x2, > + AUD96K = 0xA, > + AUD192K = 0xE, > + AUD44P1K = 0x0, > + AUD88P2K = 0x8, > + AUD176P4K = 0xC, > +}; > + > +enum it6505_aud_type { > + LPCM = 0, > + NLPCM, > + DSS, > + HBR, > +}; > + > +enum aud_word_length { > + AUD16BIT = 0, > + AUD18BIT, > + AUD20BIT, > + AUD24BIT, > +}; > + > +/* Audio Sample Word Length: AUD16BIT, AUD18BIT, AUD20BIT, AUD24BIT */ > +#define AUDWORDLENGTH AUD24BIT > + > +struct it6505_platform_data { > + struct regulator *pwr18; > + struct regulator *ovdd; > + struct gpio_desc *gpiod_hpd; > + struct gpio_desc *gpiod_pd; gpiod_pd is not used and can be deleted. > + struct gpio_desc *gpiod_reset; > + > + int hpd_irq; > + int intp_irq; hpd_irq and intp_irq are only used in one function. Drop them from it6505_platform_data and use local variables. > +}; > + > +struct it6505_dp_port { > + struct it6505 *it6505_dp; > + struct notifier_block event_nb; > + struct extcon_dev *extcon; > + struct work_struct extcon_wq; > + u8 id; It did not see this used, only assigned. Maybe I missed something? > +}; > + > +struct it6505 { > + struct drm_dp_aux aux; > + struct drm_bridge bridge; > + struct i2c_client *client; > + struct edid *edid; > + struct drm_connector connector; > + struct drm_dp_link link; > + struct it6505_platform_data pdata; > + struct mutex lock; I would be helpfull with a comment what the lock protects. > + struct regmap *regmap; > + struct it6505_dp_port *port; > + /* thread sequence control */ > + struct semaphore sem_notifier; > + > + u8 dpcd[DP_RECEIVER_CAP_SIZE]; > + enum sys_status status; > + u8 dumpdpcd[30]; > + u8 dpcd_rev; dpcd_rev is only used in one function. Drop it and use local variabel. I did not check further - please verify that all members are used and are relevant to have in this struct. > + bool hbr; > + u8 lane; > + u8 en_ssc; > + bool en_hframe; > + bool laneswap; > + > + enum it6505_aud_sel aud_sel; > + enum it6505_aud_fs aud_fs; > + enum it6505_aud_type aud_type; > + u8 aud_ch; > + u8 i2s_input_fmt; > + u8 i2s_justified; > + u8 i2s_data_delay; > + u8 i2s_ws_channel; > + u8 i2s_data_seq; > + u8 vidstable_done; > + enum aud_word_length audwordlength; > + u8 cntfsm; > + bool cp_ready; > + unsigned int bstatus; > + bool cp_done; > + u8 downstream_repeater; > + u8 am0[8]; > + u8 binfo[2]; > + u8 ksvlist[5 * 12]; > + unsigned int sha[5]; > + unsigned int w[80]; > + u8 shainput[64]; > + u8 av[5][4]; > + u8 bv[5][4]; > + u8 passsha; > + bool powered; > + /* it6505 driver hold option */ > + unsigned int it6505_drv_hold; > +}; > + > +static int it6505_poweron(struct it6505 *it6505); > +#ifdef CONFIG_DRM_ITE_IT6505_ENPWRONOFF > +static int it6505_poweroff(struct it6505 *it6505); > +#endif > + > +static const struct regmap_range it6505_bridge_volatile_ranges[] = { > + { .range_min = 0, .range_max = 0xFF }, > +}; > + > +static const struct regmap_access_table it6505_bridge_volatile_table = { > + .yes_ranges = it6505_bridge_volatile_ranges, > + .n_yes_ranges = ARRAY_SIZE(it6505_bridge_volatile_ranges), > +}; > + > +static const struct regmap_config it6505_bridge_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > + .volatile_table = &it6505_bridge_volatile_table, > + .cache_type = REGCACHE_NONE, > +}; > + > +static int dptxrd(struct it6505 *it6505, unsigned int reg_addr, > + unsigned int *value) > +{ > + int err; > + > + err = regmap_read(it6505->regmap, reg_addr, value); > + if (err < 0) { > + DRM_ERROR("%s read fail err reg_addr[0x%x] err:%d\n", > + __func__, reg_addr, err); > + return err; > + } > + > + return 0; > +} > + > +static void it6505_dump(struct it6505 *it6505) > +{ > + unsigned int value, i; > + > + DRM_DEBUG_DRIVER("\n----------%s start----------\n", __func__); > + for (i = 0; i <= 0xff; i++) { > + dptxrd(it6505, i, &value); > + DRM_DEBUG_DRIVER("%s[0x%x] = 0x%x\n", __func__, i, value); > + } > + DRM_DEBUG_DRIVER("\n----------%s end----------\n\n", __func__); > +} Are these headers really needed in a production driver? > + > +static int dptxwr(struct it6505 *it6505, unsigned int reg_addr, > + unsigned int reg_val) > +{ > + int err; > + > + err = regmap_write(it6505->regmap, reg_addr, reg_val); > + > + if (err < 0) { > + DRM_ERROR("%s write fail err reg[0x%x] = 0x%x err = %d\n", > + __func__, reg_addr, reg_val, err); > + return err; > + } > + > + return 0; > +} > + > +static int dptxset(struct it6505 *it6505, unsigned int reg, unsigned int mask, > + unsigned int value) > +{ > + int err; > + > + err = regmap_update_bits(it6505->regmap, reg, mask, value); > + if (err < 0) { > + DRM_ERROR("%s write fail err %d\n", __func__, err); > + return err; > + } > + > + return 0; > +} > + > +static inline struct it6505 *connector_to_it6505(struct drm_connector *c) > +{ > + return container_of(c, struct it6505, connector); > +} > + > +static inline struct it6505 *bridge_to_it6505(struct drm_bridge *bridge) > +{ > + return container_of(bridge, struct it6505, bridge); > +} > + > +static void it6505_init_fsm(struct it6505 *it6505) > +{ > + it6505->aud_sel = AUDSEL; > + it6505->aud_fs = AUDFS; > + it6505->aud_ch = AUDCH; > + it6505->aud_type = AUDTYPE; > + it6505->i2s_input_fmt = I2SINPUTFMT; > + it6505->i2s_justified = I2SJUSTIFIED; > + it6505->i2s_data_delay = I2SDATADELAY; > + it6505->i2s_ws_channel = I2SWSCHANNEL; > + it6505->i2s_data_seq = I2SDATASEQ; > + it6505->audwordlength = AUDWORDLENGTH; > + > + it6505->status = SYS_Unknown; > + it6505->hbr = _HBR; > + it6505->lane = LANE; > + it6505->en_ssc = ENSSC; > + it6505->en_hframe = ENHFRAME; > + it6505->laneswap = LANESWAP; > + it6505->vidstable_done = 0; > +} > + > +#if (CHIP_VERSION == BX) > +static void it6505_termination(struct it6505 *it6505, bool s) > +{ > + DRM_DEBUG_DRIVER("%s switch!!\n", __func__); > + if (s) { > + dptxset(it6505, 0x5D, 0x80, 0x00); > + dptxset(it6505, 0x5E, 0x02, 0x02); > + DRM_DEBUG_DRIVER("%s ON!!\n", __func__); > + } else { > + dptxset(it6505, 0x5D, 0x80, 0x80); > + dptxset(it6505, 0x5E, 0x02, 0x00); > + dptxset(it6505, 0x5C, 0xF0, 0x00); > + DRM_DEBUG_DRIVER("%s OFF!!\n", __func__); > + } > +} > +#endif > + > +static bool dptx_getsinkhpd(struct it6505 *it6505) > +{ > + unsigned int value; > + int ret; > + > + ret = dptxrd(it6505, 0x0D, &value); > + > + if (ret < 0) > + return false; > + > + return (value & 2) == 2; > +} > + > +static void show_vid_info(struct it6505 *it6505) > +{ > + int hsync_pol, vsync_pol, interlaced; > + int htotal, hdes, hdew, hfph, hsyncw; > + int vtotal, vdes, vdew, vfph, vsyncw; > + int rddata, rddata1, i; > + int pclk, sum; > + > + usleep_range(10000, 15000); > + dptxwr(it6505, 0x0F, 0x00); > + dptxrd(it6505, 0xa0, &rddata); > + hsync_pol = rddata & BIT(0); > + vsync_pol = (rddata & BIT(2)) >> 2; > + interlaced = (rddata & BIT(4)) >> 4; > + > + dptxrd(it6505, 0xa1, &rddata); > + dptxrd(it6505, 0xa2, &rddata1); > + htotal = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xa3, &rddata); > + dptxrd(it6505, 0xa4, &rddata1); > + > + hdes = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xa5, &rddata); > + dptxrd(it6505, 0xa6, &rddata1); > + > + hdew = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xa7, &rddata); > + dptxrd(it6505, 0xa8, &rddata1); > + > + hfph = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xa9, &rddata); > + dptxrd(it6505, 0xaa, &rddata1); > + > + hsyncw = ((rddata1 & 0x1F) << 8) + rddata; > + > + dptxrd(it6505, 0xab, &rddata); > + dptxrd(it6505, 0xac, &rddata1); > + vtotal = ((rddata1 & 0x0F) << 8) + rddata; > + > + dptxrd(it6505, 0xad, &rddata); > + dptxrd(it6505, 0xae, &rddata1); > + vdes = ((rddata1 & 0x0F) << 8) + rddata; > + > + dptxrd(it6505, 0xaf, &rddata); > + dptxrd(it6505, 0xb0, &rddata1); > + vdew = ((rddata1 & 0x0F) << 8) + rddata; > + > + dptxrd(it6505, 0xb1, &rddata); > + dptxrd(it6505, 0xb2, &rddata1); > + vfph = ((rddata1 & 0x0F) << 8) + rddata; > + > + dptxrd(it6505, 0xb3, &rddata); > + dptxrd(it6505, 0xb4, &rddata1); > + vsyncw = ((rddata1 & 0x0F) << 8) + rddata; > + > + sum = 0; > + for (i = 0; i < 100; i++) { > + dptxset(it6505, 0x12, 0x80, 0x80); > + usleep_range(10000, 15000); > + dptxset(it6505, 0x12, 0x80, 0x00); > + > + dptxrd(it6505, 0x13, &rddata); > + dptxrd(it6505, 0x14, &rddata1); > + rddata = ((rddata1 & 0x0F) << 8) + rddata; > + > + sum += rddata; > + } > + > + sum /= 100; > + pclk = 13500 * 2048 / sum; > + > + DRM_DEBUG_DRIVER("\n----------Video Input Timing----------\n"); > + DRM_DEBUG_DRIVER("PCLK = %d.%dMHz\n", pclk / 1000, pclk % 1000); > + DRM_DEBUG_DRIVER("HTotal = %d\n", htotal); > + DRM_DEBUG_DRIVER("HActive = %d\n", hdew); > + DRM_DEBUG_DRIVER("HFrontPorch = %d\n", hfph); > + DRM_DEBUG_DRIVER("HSyncWidth = %d\n", hsyncw); > + DRM_DEBUG_DRIVER("HBackPorch = %d\n", htotal - hdew - hfph - hsyncw); > + DRM_DEBUG_DRIVER("VTotal = %d\n", vtotal); > + DRM_DEBUG_DRIVER("VActive = %d\n", vdew); > + DRM_DEBUG_DRIVER("VFrontPorch = %d\n", vfph); > + DRM_DEBUG_DRIVER("VSyncWidth = %d\n", vsyncw); > + DRM_DEBUG_DRIVER("VBackPorch = %d\n", vtotal - vdew - vfph - vsyncw); Can DRM_MODE_FMT and DRM_MODE_ARG be used here? > +} > + > +static void dptx_sys_chg(struct it6505 *it6505, enum sys_status newstate) > +{ > + unsigned int i = 0; > + unsigned int reg06, reg07, reg08, reg0d, reg0e; > + > + dptxrd(it6505, 0x06, ®06); > + dptxrd(it6505, 0x07, ®07); > + dptxrd(it6505, 0x08, ®08); > + dptxrd(it6505, 0x0d, ®0d); > + dptxrd(it6505, 0x0e, ®0e); > + > + DRM_DEBUG_DRIVER("[%s]reg06 = 0x%x\n", __func__, reg06); > + DRM_DEBUG_DRIVER("[%s]reg07 = 0x%x\n", __func__, reg07); > + DRM_DEBUG_DRIVER("[%s]reg08 = 0x%x\n", __func__, reg08); > + DRM_DEBUG_DRIVER("[%s]reg0d = 0x%x\n", __func__, reg0d); > + DRM_DEBUG_DRIVER("[%s]reg0e = 0x%x\n", __func__, reg0e); Looks like debugging artifacts that are not relevant in a production driver. > + > + if (newstate != SYS_UNPLUG) { > + if (!dptx_getsinkhpd(it6505)) > + newstate = SYS_UNPLUG; > + } > + > + it6505->status = newstate; > + > + switch (it6505->status) { > + case SYS_UNPLUG: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_UNPLUG!"); > + kfree(it6505->edid); > + it6505->edid = NULL; > + DRM_DEBUG_DRIVER("Free it6505 EDID memory!"); > +#if (CHIP_VERSION == BX) > + it6505_termination(it6505, false); > +#endif > + break; > + case SYS_HPD: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_HPD!"); > +#if (CHIP_VERSION == BX) > + it6505_termination(it6505, true); > +#endif > + break; > + case SYS_AUTOTRAIN: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_AUTOTRAIN!"); > + break; > + case SYS_WAIT: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_WAIT!"); > + break; > +#ifdef CONFIG_DRM_ITE_IT6505_ENHDCP > + case SYS_ReHDCP: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_ReHDCP!"); > + break; > +#endif > + case SYS_NOROP: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_NOROP!"); > + for (i = 0; i < SHOWVIDEOTIMING; i++) > + show_vid_info(it6505); > +#ifdef TEST_MODE > + it6505->it6505_drv_hold = 1; > + DRM_DEBUG_DRIVER("set it6505_drv_hold:%d", > + it6505->it6505_drv_hold); > +#endif > + break; > + case SYS_PWRDN: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_PWRDN!"); > + /* Reset and PwrDn AFE */ > + break; > + default: > + DRM_DEBUG_DRIVER("sys_state is changing to SYS_UNKNOWN!"); > + break; > + } > +} I browsed the driver and did not find anything other than issues that are already reported above. As I have no experience with a bridge driver as such the functionality was not looked at. Sam