From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yakir Yang Subject: Re: [PATCH v3 1/2] drm: rockchip/hdmi: add Innosilicon HDMI support Date: Mon, 25 Jan 2016 09:22:31 +0800 Message-ID: <56A578D7.5070101@rock-chips.com> References: <1452850598-30859-1-git-send-email-ykk@rock-chips.com> <1452850690-31760-1-git-send-email-ykk@rock-chips.com> <569C3E36.10103@rock-chips.com> <56A47E6F.8050104@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <56A47E6F.8050104@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Caesar Wang Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-rockchip@lists.infradead.org, Rob Herring , Thierry Reding , linux-arm-kernel@lists.infradead.org List-Id: linux-rockchip.vger.kernel.org SGkgQ2Flc2FyLAoKCk9uIDAxLzI0LzIwMTYgMDM6MzQgUE0sIENhZXNhciBXYW5nIHdyb3RlOgo+ IEhpCj4KPiDlnKggMjAxNuW5tDAx5pyIMTjml6UgMDk6MjEsIE1hcmsgeWFvIOWGmemBkzoKPj4g SGkgWWFraXIKPj4KPj4gSSdkIGxpa2UgeW91IGNhbiBjaGFuZ2UgeW91ciBwYXRjaCB0aXRsZSBp bnRvICJkcm0vcm9ja2NoaXAvaGRtaSIsIHNvIAo+PiB3aGVuIEkgc2VhcmNoIHBhdGNoZXMgdXNl ICJkcm0vcm9ja2NoaXAiIGNhbiBmaW5kIHlvdXIgcGF0Y2guCj4+Cj4+IGFuZCBJIGhhdmUgc29t ZSBhZHZpY2VzIG1haWwgaW5saW5lLgo+Pgo+PiBUaGFua3M6LSkKPj4KPj4gT24gMjAxNuW5tDAx 5pyIMTXml6UgMTc6MzgsIFlha2lyIFlhbmcgd3JvdGU6Cj4+PiBUaGUgSW5ub3NpbGljb24gSERN SSBpcyBhIGxvdyBwb3dlciBIRE1JIDEuNCB0cmFuc21pdHRlcgo+Pj4gSVAsIGFuZCBpdCBoYXZl IGJlZW4gaW50ZWdyYXRlZCBvbiBzb21lIHJvY2tjaGlwIENQVXMKPj4+IChsaWtlIFJLMzAzNiwg UkszMTJ4KS4KPj4+Cj4+PiBTaWduZWQtb2ZmLWJ5OiBZYWtpciBZYW5nIDx5a2tAcm9jay1jaGlw cy5jb20+Cj4+PiAtLS0KPj4+IENoYW5nZXMgaW4gdjM6Cj4+PiAtIFVzZSBlbmNvZGVyIGVuYWJs ZS9kaXNhYmxlIGZ1bmN0aW9uLCBhbmQgcmVtb3ZlIHRoZSBlbmNvZGVyIERQTVMgCj4+PiBmdW5j dGlvbgo+Pj4gLSBLZWVwIEhETUkgUExMIHBvd2VyIG9uIGluIHN0YW5kYnkgbW9kZQo+Pj4KPj4+ IENoYW5nZXMgaW4gdjI6Cj4+PiAtIFVzaW5nIERSTSBhdG9taWMgaGVscGVyIGZ1bmN0aW9ucyBm b3IgY29ubmVjdG9yIGluaXQgKE1hcmspCj4+PiAtIFJlbW92ZSAiaGRtaS0+Y29ubmVjdG9yLmVu Y29kZXIgPSBlbmNvZGVyOyIgKE1hcmspCj4+Pgo+Pj4gICBkcml2ZXJzL2dwdS9kcm0vcm9ja2No aXAvS2NvbmZpZyAgICAgfCAgIDggKwo+Pj4gICBkcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvTWFr ZWZpbGUgICAgfCAgIDEgKwo+Pj4gICBkcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1p LmMgfCA5OTkgCj4+PiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+Pj4gICBk cml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmggfCAzNjQgKysrKysrKysrKysrKwo+ Pj4gICA0IGZpbGVzIGNoYW5nZWQsIDEzNzIgaW5zZXJ0aW9ucygrKQo+Pj4gICBjcmVhdGUgbW9k ZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL2lubm9faGRtaS5jCj4+PiAgIGNyZWF0 ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmgKPj4+Cj4+ PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL0tjb25maWcgCj4+PiBiL2Ry aXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9LY29uZmlnCj4+PiBpbmRleCAzNTIxNWY2Li5hNTAxNGUw IDEwMDY0NAo+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL0tjb25maWcKPj4+ICsr KyBiL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9LY29uZmlnCj4+PiBAQCAtMjUsMyArMjUsMTEg QEAgY29uZmlnIFJPQ0tDSElQX0RXX0hETUkKPj4+ICAgICAgICAgZm9yIHRoZSBTeW5vcHN5cyBE ZXNpZ25XYXJlIEhETUkgZHJpdmVyLiBJZiB5b3Ugd2FudCB0bwo+Pj4gICAgICAgICBlbmFibGUg SERNSSBvbiBSSzMyODggYmFzZWQgU29DLCB5b3Ugc2hvdWxkIHNlbGV0IHRoaXMKPj4+ICAgICAg ICAgb3B0aW9uLgo+Pj4gKwo+Pj4gK2NvbmZpZyBST0NLQ0hJUF9JTk5PX0hETUkKPj4+ICsgICAg dHJpc3RhdGUgIlJvY2tjaGlwIHNwZWNpZmljIGV4dGVuc2lvbnMgZm9yIElubm9zaWxpY29uIEhE TUkiCj4+PiArICAgICAgICBkZXBlbmRzIG9uIERSTV9ST0NLQ0hJUAo+Pj4gKyAgICAgICAgaGVs cAo+Pj4gKyAgICAgIFRoaXMgc2VsZWN0cyBzdXBwb3J0IGZvciBSb2NrY2hpcCBTb0Mgc3BlY2lm aWMgZXh0ZW5zaW9ucwo+Pj4gKyAgICAgIGZvciB0aGUgSW5ub3NpbGljb24gSERNSSBkcml2ZXIu IElmIHlvdSB3YW50IHRvIGVuYWJsZQo+Pj4gKyAgICAgIEhETUkgb24gUkszMDM2IGJhc2VkIFNv QywgeW91IHNob3VsZCBzZWxldCB0aGlzIG9wdGlvbi4KPgo+IFRoYXQncyBzZWVtIGhhcyBzb21l IGNvbmZsaWN0cyBzaW5jZSB0aGUgTUlQSSBkcml2ZXIgbGFuZCBpbiBtYWlubGluZS4KPiBTbyB5 b3UgbmVlZCB1cGRhdGUgaXQgYmFzZWQgb24gdGhlIGxhc3Rlc3Qga2VybmVsLgo+CgpZZXAsIHRo YW5rcyBmb3IgeW91ciByZW1pbmRlciwgbmVlZCB0byB1cGRhdGUgdGhlIHBhdGNoLiBBbmQgYnkg dGhlIHdheQp0aGUgbGF0ZXN0IHZlcnNpb24gb2YgdGhpcyBwYXRjaCBoYXZlIGJlZW4gdXBkYXRl ZCB0byB2NSAgOikKICAgICBodHRwczovL3BhdGNod29yay5rZXJuZWwub3JnL3BhdGNoLzgwNTgw NjEvCgo+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9NYWtlZmlsZSAK Pj4+IGIvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL01ha2VmaWxlCj4+PiBpbmRleCBhOWQzODBm Li5kYTJiZjc2IDEwMDY0NAo+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL01ha2Vm aWxlCj4+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvTWFrZWZpbGUKPj4+IEBAIC02 LDYgKzYsNyBAQCByb2NrY2hpcGRybS15IDo9IHJvY2tjaGlwX2RybV9kcnYubyAKPj4+IHJvY2tj aGlwX2RybV9mYi5vIHJvY2tjaGlwX2RybV9mYmRldi5vIFwKPj4+ICAgICAgICAgICByb2NrY2hp cF9kcm1fZ2VtLm8KPj4+ICAgICBvYmotJChDT05GSUdfUk9DS0NISVBfRFdfSERNSSkgKz0gZHdf aGRtaS1yb2NrY2hpcC5vCj4+PiArb2JqLSQoQ09ORklHX1JPQ0tDSElQX0lOTk9fSERNSSkgKz0g aW5ub19oZG1pLm8KPj4+ICAgICBvYmotJChDT05GSUdfRFJNX1JPQ0tDSElQKSArPSByb2NrY2hp cGRybS5vIHJvY2tjaGlwX2RybV92b3AubyBcCj4+PiAgICAgICAgICAgICAgICAgICByb2NrY2hp cF92b3BfcmVnLm8KPj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5u b19oZG1pLmMgCj4+PiBiL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9pbm5vX2hkbWkuYwo+Pj4g bmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4+IGluZGV4IDAwMDAwMDAuLmRjOTgxNzkKPj4+IC0tLSAv ZGV2L251bGwKPj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9pbm5vX2hkbWkuYwo+ Pj4gQEAgLTAsMCArMSw5OTkgQEAKPj4+ICsvKgo+Pj4gKyAqIENvcHlyaWdodCAoQykgRnV6aG91 IFJvY2tjaGlwIEVsZWN0cm9uaWNzIENvLkx0ZAo+Pj4gKyAqICAgIFpoZW5nIFlhbmcgPHpoZW5n eWFuZ0Byb2NrLWNoaXBzLmNvbT4KPj4+ICsgKiAgICBZYWtpciBZYW5nIDx5a2tAcm9jay1jaGlw cy5jb20+Cj4+PiArICoKPj4+ICsgKiBUaGlzIHNvZnR3YXJlIGlzIGxpY2Vuc2VkIHVuZGVyIHRo ZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljCj4+PiArICogTGljZW5zZSB2ZXJzaW9u IDIsIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCAKPj4+IGFu ZAo+Pj4gKyAqIG1heSBiZSBjb3BpZWQsIGRpc3RyaWJ1dGVkLCBhbmQgbW9kaWZpZWQgdW5kZXIg dGhvc2UgdGVybXMuCj4+PiArICoKPj4+ICsgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQg aW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKPj4+ICsgKiBidXQgV0lUSE9VVCBB TlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgo+Pj4gKyAq IE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNl ZSB0aGUKPj4+ICsgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxz Lgo+Pj4gKyAqLwo+Pj4gKwo+Pj4gKyNpbmNsdWRlIDxsaW51eC9pcnEuaD4KPj4+ICsjaW5jbHVk ZSA8bGludXgvY2xrLmg+Cj4+PiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+Cj4+PiArI2luY2x1 ZGUgPGxpbnV4L2Vyci5oPgo+Pj4gKyNpbmNsdWRlIDxsaW51eC9oZG1pLmg+Cj4+PiArI2luY2x1 ZGUgPGxpbnV4L21mZC9zeXNjb24uaD4KPj4+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+ PiArI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+Cj4+PiArI2luY2x1ZGUgPGxpbnV4L29mX2Rldmlj ZS5oPgo+Pj4gKwo+Pj4gKyNpbmNsdWRlIDxkcm0vZHJtX29mLmg+Cj4+PiArI2luY2x1ZGUgPGRy bS9kcm1QLmg+Cj4+PiArI2luY2x1ZGUgPGRybS9kcm1fYXRvbWljX2hlbHBlci5oPgo+Pj4gKyNp bmNsdWRlIDxkcm0vZHJtX2NydGNfaGVscGVyLmg+Cj4+PiArI2luY2x1ZGUgPGRybS9kcm1fZWRp ZC5oPgo+Pj4gKyNpbmNsdWRlIDxkcm0vZHJtX2VuY29kZXJfc2xhdmUuaD4KPj4+ICsKPj4+ICsj aW5jbHVkZSAicm9ja2NoaXBfZHJtX2Rydi5oIgo+Pj4gKyNpbmNsdWRlICJyb2NrY2hpcF9kcm1f dm9wLmgiCj4+PiArCj4+PiArI2luY2x1ZGUgImlubm9faGRtaS5oIgo+Pj4gKwo+Pj4gKyNkZWZp bmUgdG9faW5ub19oZG1pKHgpICAgIGNvbnRhaW5lcl9vZih4LCBzdHJ1Y3QgaW5ub19oZG1pLCB4 KQo+Pj4gKwo+Pj4gK3N0cnVjdCBoZG1pX2RhdGFfaW5mbyB7Cj4+PiArICAgIGludCB2aWM7Cj4+ PiArICAgIGJvb2wgc2lua19pc19oZG1pOwo+Pj4gKyAgICBib29sIHNpbmtfaGFzX2F1ZGlvOwo+ Pj4gKyAgICB1bnNpZ25lZCBpbnQgZW5jX2luX2Zvcm1hdDsKPj4+ICsgICAgdW5zaWduZWQgaW50 IGVuY19vdXRfZm9ybWF0Owo+Pj4gKyAgICB1bnNpZ25lZCBpbnQgY29sb3JpbWV0cnk7Cj4+PiAr fTsKPj4+ICsKPj4+ICtzdHJ1Y3QgaW5ub19oZG1pX2kyYyB7Cj4+PiArICAgIHN0cnVjdCBpMmNf YWRhcHRlciBhZGFwOwo+Pj4gKwo+Pj4gKyAgICB1OCBkZGNfYWRkcjsKPj4+ICsgICAgdTggc2Vn bWVudF9hZGRyOwo+Pj4gKwo+Pj4gKyAgICBzdHJ1Y3QgbXV0ZXggbG9jazsKPj4+ICsgICAgc3Ry dWN0IGNvbXBsZXRpb24gY21wOwo+Pj4gK307Cj4+PiArCj4+PiArc3RydWN0IGlubm9faGRtaSB7 Cj4+PiArICAgIHN0cnVjdCBkZXZpY2UgKmRldjsKPj4+ICsgICAgc3RydWN0IGRybV9kZXZpY2Ug KmRybV9kZXY7Cj4+PiArCj4+PiArICAgIGludCBpcnE7Cj4+PiArICAgIHN0cnVjdCBjbGsgKnBj bGs7Cj4+PiArICAgIHZvaWQgX19pb21lbSAqcmVnczsKPj4+ICsKPj4+ICsgICAgc3RydWN0IGRy bV9jb25uZWN0b3IgICAgY29ubmVjdG9yOwo+Pj4gKyAgICBzdHJ1Y3QgZHJtX2VuY29kZXIgICAg ZW5jb2RlcjsKPj4+ICsKPj4+ICsgICAgc3RydWN0IGlubm9faGRtaV9pMmMgKmkyYzsKPj4+ICsg ICAgc3RydWN0IGkyY19hZGFwdGVyICpkZGM7Cj4+PiArCj4+PiArICAgIHVuc2lnbmVkIGludCB0 bWRzX3JhdGU7Cj4+PiArCj4+PiArICAgIHN0cnVjdCBoZG1pX2RhdGFfaW5mbyAgICBoZG1pX2Rh dGE7Cj4+PiArICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlIHByZXZpb3VzX21vZGU7Cj4+PiAr fTsKPj4+ICsKPj4+ICtlbnVtIHsKPj4+ICsgICAgQ1NDX0lUVTYwMV8xNl8yMzVfVE9fUkdCXzBf MjU1XzhCSVQsCj4+PiArICAgIENTQ19JVFU2MDFfMF8yNTVfVE9fUkdCXzBfMjU1XzhCSVQsCj4+ PiArICAgIENTQ19JVFU3MDlfMTZfMjM1X1RPX1JHQl8wXzI1NV84QklULAo+Pj4gKyAgICBDU0Nf UkdCXzBfMjU1X1RPX0lUVTYwMV8xNl8yMzVfOEJJVCwKPj4+ICsgICAgQ1NDX1JHQl8wXzI1NV9U T19JVFU3MDlfMTZfMjM1XzhCSVQsCj4+PiArICAgIENTQ19SR0JfMF8yNTVfVE9fUkdCXzE2XzIz NV84QklULAo+Pj4gK307Cj4+PiArCj4+PiArc3RhdGljIGNvbnN0IGNoYXIgY29lZmZfY3NjW11b MjRdID0gewo+Pj4gKyAgICAvKgo+Pj4gKyAgICAgKiBZVVYyUkdCOjYwMSBTRCBtb2RlKFlbMTY6 MjM1XSwgVVZbMTY6MjQwXSwgUkdCWzA6MjU1XSk6Cj4+PiArICAgICAqICAgUiA9IDEuMTY0Klkg KyAxLjU5NipWIC0gMjA0Cj4+PiArICAgICAqICAgRyA9IDEuMTY0KlkgLSAwLjM5MSpVIC0gMC44 MTMqViArIDE1NAo+Pj4gKyAgICAgKiAgIEIgPSAxLjE2NCpZICsgMi4wMTgqVSAtIDI1OAo+Pj4g KyAgICAgKi8KPj4+ICsgICAgewo+Pj4gKyAgICAgICAgMHgwNCwgMHhhNywgMHgwMCwgMHgwMCwg MHgwNiwgMHg2MiwgMHgwMiwgMHhjYywKPj4+ICsgICAgICAgIDB4MDQsIDB4YTcsIDB4MTEsIDB4 OTAsIDB4MTMsIDB4NDAsIDB4MDAsIDB4OWEsCj4+PiArICAgICAgICAweDA0LCAweGE3LCAweDA4 LCAweDEyLCAweDAwLCAweDAwLCAweDAzLCAweDAyCj4+PiArICAgIH0sCj4+PiArICAgIC8qCj4+ PiArICAgICAqIFlVVjJSR0I6NjAxIFNEIG1vZGUoWVVWWzA6MjU1XSxSR0JbMDoyNTVdKToKPj4+ ICsgICAgICogICBSID0gWSArIDEuNDAyKlYgLSAyNDgKPj4+ICsgICAgICogICBHID0gWSAtIDAu MzQ0KlUgLSAwLjcxNCpWICsgMTM1Cj4+PiArICAgICAqICAgQiA9IFkgKyAxLjc3MipVIC0gMjI3 Cj4+PiArICAgICAqLwo+Pj4gKyAgICB7Cj4+PiArICAgICAgICAweDA0LCAweDAwLCAweDAwLCAw eDAwLCAweDA1LCAweDliLCAweDAyLCAweGY4LAo+Pj4gKyAgICAgICAgMHgwNCwgMHgwMCwgMHgx MSwgMHg2MCwgMHgxMiwgMHhkYiwgMHgwMCwgMHg4NywKPj4+ICsgICAgICAgIDB4MDQsIDB4MDAs IDB4MDcsIDB4MTYsIDB4MDAsIDB4MDAsIDB4MDIsIDB4ZTMKPj4+ICsgICAgfSwKPj4+ICsgICAg LyoKPj4+ICsgICAgICogWVVWMlJHQjo3MDkgSEQgbW9kZShZWzE2OjIzNV0sVVZbMTY6MjQwXSxS R0JbMDoyNTVdKToKPj4+ICsgICAgICogICBSID0gMS4xNjQqWSArIDEuNzkzKlYgLSAyNDgKPj4+ ICsgICAgICogICBHID0gMS4xNjQqWSAtIDAuMjEzKlUgLSAwLjUzNCpWICsgNzcKPj4+ICsgICAg ICogICBCID0gMS4xNjQqWSArIDIuMTE1KlUgLSAyODkKPj4+ICsgICAgICovCj4+PiArICAgIHsK Pj4+ICsgICAgICAgIDB4MDQsIDB4YTcsIDB4MDAsIDB4MDAsIDB4MDcsIDB4MmMsIDB4MDIsIDB4 ZjgsCj4+PiArICAgICAgICAweDA0LCAweGE3LCAweDEwLCAweGRhLCAweDEyLCAweDIyLCAweDAw LCAweDRkLAo+Pj4gKyAgICAgICAgMHgwNCwgMHhhNywgMHgwOCwgMHg3NCwgMHgwMCwgMHgwMCwg MHgwMywgMHgyMQo+Pj4gKyAgICB9LAo+Pj4gKwo+Pj4gKyAgICAvKgo+Pj4gKyAgICAgKiBSR0Iy WVVWOjYwMSBTRCBtb2RlOgo+Pj4gKyAgICAgKiAgIENiID0gLTAuMjkxRyAtIDAuMTQ4UiArIDAu NDM5QiArIDEyOAo+Pj4gKyAgICAgKiAgIFkgID0gMC41MDRHICArIDAuMjU3UiArIDAuMDk4QiAr IDE2Cj4+PiArICAgICAqICAgQ3IgPSAtMC4zNjhHICsgMC40MzlSIC0gMC4wNzFCICsgMTI4Cj4+ PiArICAgICAqLwo+Pj4gKyAgICB7Cj4+PiArICAgICAgICAweDExLCAweDVmLCAweDAxLCAweDgy LCAweDEwLCAweDIzLCAweDAwLCAweDgwLAo+Pj4gKyAgICAgICAgMHgwMiwgMHgxYywgMHgwMCwg MHhhMSwgMHgwMCwgMHgzNiwgMHgwMCwgMHgxZSwKPj4+ICsgICAgICAgIDB4MTEsIDB4MjksIDB4 MTAsIDB4NTksIDB4MDEsIDB4ODIsIDB4MDAsIDB4ODAKPj4+ICsgICAgfSwKPj4+ICsgICAgLyoK Pj4+ICsgICAgICogUkdCMllVVjo3MDkgSEQgbW9kZToKPj4+ICsgICAgICogICBDYiA9IC0gMC4z MzhHIC0gMC4xMDFSICsgMC40MzlCICsgMTI4Cj4+PiArICAgICAqICAgWSAgPSAwLjYxNEcgICAr IDAuMTgzUiArIDAuMDYyQiArIDE2Cj4+PiArICAgICAqICAgQ3IgPSAtIDAuMzk5RyArIDAuNDM5 UiAtIDAuMDQwQiArIDEyOAo+Pj4gKyAgICAgKi8KPj4+ICsgICAgewo+Pj4gKyAgICAgICAgMHgx MSwgMHg5OCwgMHgwMSwgMHhjMSwgMHgxMCwgMHgyOCwgMHgwMCwgMHg4MCwKPj4+ICsgICAgICAg IDB4MDIsIDB4NzQsIDB4MDAsIDB4YmIsIDB4MDAsIDB4M2YsIDB4MDAsIDB4MTAsCj4+PiArICAg ICAgICAweDExLCAweDVhLCAweDEwLCAweDY3LCAweDAxLCAweGMxLCAweDAwLCAweDgwCj4+PiAr ICAgIH0sCj4+PiArICAgIC8qCj4+PiArICAgICAqIFJHQlswOjI1NV0yUkdCWzE2OjIzNV06Cj4+ PiArICAgICAqICAgUicgPSBSIHggKDIzNS0xNikvMjU1ICsgMTY7Cj4+PiArICAgICAqICAgRycg PSBHIHggKDIzNS0xNikvMjU1ICsgMTY7Cj4+PiArICAgICAqICAgQicgPSBCIHggKDIzNS0xNikv MjU1ICsgMTY7Cj4+PiArICAgICAqLwo+Pj4gKyAgICB7Cj4+PiArICAgICAgICAweDAwLCAweDAw LCAweDAzLCAweDZGLCAweDAwLCAweDAwLCAweDAwLCAweDEwLAo+Pj4gKyAgICAgICAgMHgwMywg MHg2RiwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgxMCwKPj4+ICsgICAgICAgIDB4 MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDMsIDB4NkYsIDB4MDAsIDB4MTAKPj4+ICsgICAgfSwK Pj4+ICt9Owo+Pj4gKwo+Pj4gK3N0YXRpYyBpbmxpbmUgdTggaGRtaV9yZWFkYihzdHJ1Y3QgaW5u b19oZG1pICpoZG1pLCB1MTYgb2Zmc2V0KQo+Pj4gK3sKPj4+ICsgICAgcmV0dXJuIHJlYWRsX3Jl bGF4ZWQoaGRtaS0+cmVncyArIChvZmZzZXQpICogMHgwNCk7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0 YXRpYyBpbmxpbmUgdm9pZCBoZG1pX3dyaXRlYihzdHJ1Y3QgaW5ub19oZG1pICpoZG1pLCB1MTYg b2Zmc2V0LCAKPj4+IHUzMiB2YWwpCj4+PiArewo+Pj4gKyAgICB3cml0ZWxfcmVsYXhlZCh2YWws IGhkbWktPnJlZ3MgKyAob2Zmc2V0KSAqIDB4MDQpOwo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMg aW5saW5lIHZvaWQgaGRtaV9tb2RiKHN0cnVjdCBpbm5vX2hkbWkgKmhkbWksIHUxNiBvZmZzZXQs Cj4+PiArICAgICAgICAgICAgICAgICB1MzIgbXNrLCB1MzIgdmFsKQo+Pj4gK3sKPj4+ICsgICAg dTggdGVtcCA9IGhkbWlfcmVhZGIoaGRtaSwgb2Zmc2V0KSAmIH5tc2s7Cj4+PiArCj4+PiArICAg IHRlbXAgfD0gdmFsICYgbXNrOwo+Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBvZmZzZXQsIHRl bXApOwo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMgdm9pZCBpbm5vX2hkbWlfaTJjX2luaXQoc3Ry dWN0IGlubm9faGRtaSAqaGRtaSkKPj4+ICt7Cj4+PiArICAgIGludCBkZGNfYnVzX2ZyZXE7Cj4+ PiArCj4+PiArICAgIGRkY19idXNfZnJlcSA9IChoZG1pLT50bWRzX3JhdGUgPj4gMikgLyBIRE1J X1NDTF9SQVRFOwo+Pj4gKwo+Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBERENfQlVTX0ZSRVFf TCwgZGRjX2J1c19mcmVxICYgMHhGRik7Cj4+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEREQ19C VVNfRlJFUV9ILCAoZGRjX2J1c19mcmVxID4+IDgpICYgMHhGRik7Cj4+PiArCj4+PiArICAgIC8q IENsZWFyIHRoZSBFRElEIGludGVycnVwdCBmbGFnIGFuZCBtdXRlIHRoZSBpbnRlcnJ1cHQgKi8K Pj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9JTlRFUlJVUFRfTUFTSzEsIDApOwo+Pj4g KyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX0lOVEVSUlVQVF9TVEFUVVMxLCBtX0lOVF9FRElE X1JFQURZKTsKPj4+ICt9Cj4+PiArCj4+PiArc3RhdGljIHZvaWQgaW5ub19oZG1pX3N5c19wb3dl cihzdHJ1Y3QgaW5ub19oZG1pICpoZG1pLCBib29sIGVuYWJsZSkKPj4+ICt7Cj4+PiArICAgIGlm IChlbmFibGUpCj4+PiArICAgICAgICBoZG1pX21vZGIoaGRtaSwgSERNSV9TWVNfQ1RSTCwgbV9Q T1dFUiwgdl9QV1JfT04pOwo+Pj4gKyAgICBlbHNlCj4+PiArICAgICAgICBoZG1pX21vZGIoaGRt aSwgSERNSV9TWVNfQ1RSTCwgbV9QT1dFUiwgdl9QV1JfT0ZGKTsKPj4+ICt9Cj4+PiArCj4+PiAr c3RhdGljIHZvaWQgaW5ub19oZG1pX3NldF9wd3JfbW9kZShzdHJ1Y3QgaW5ub19oZG1pICpoZG1p LCBpbnQgbW9kZSkKPj4+ICt7Cj4+PiArICAgIHN3aXRjaCAobW9kZSkgewo+Pj4gKyAgICBjYXNl IE5PUk1BTDoKPj4+ICsgICAgICAgIGlubm9faGRtaV9zeXNfcG93ZXIoaGRtaSwgZmFsc2UpOwo+ Pj4gKwo+Pj4gKyAgICAgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9QSFlfUFJFX0VNUEhBU0lT LCAweDZmKTsKPj4+ICsgICAgICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfUEhZX0RSSVZFUiwg MHhiYik7Cj4+PiArCj4+PiArICAgICAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1BIWV9TWVNf Q1RMLCAweDE1KTsKPj4+ICsgICAgICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfUEhZX1NZU19D VEwsIDB4MTQpOwo+Pj4gKyAgICAgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9QSFlfU1lTX0NU TCwgMHgxMCk7Cj4+PiArICAgICAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1BIWV9DSEdfUFdS LCAweDBmKTsKPj4+ICsgICAgICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfUEhZX1NZTkMsIDB4 MDApOwo+Pj4gKyAgICAgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9QSFlfU1lOQywgMHgwMSk7 Cj4+PiArCj4+PiArICAgICAgICBpbm5vX2hkbWlfc3lzX3Bvd2VyKGhkbWksIHRydWUpOwo+Pj4g KyAgICAgICAgYnJlYWs7Cj4+PiArCj4+PiArICAgIGNhc2UgTE9XRVJfUFdSOgo+Pj4gKyAgICAg ICAgaW5ub19oZG1pX3N5c19wb3dlcihoZG1pLCBmYWxzZSk7Cj4+PiArICAgICAgICBoZG1pX3dy aXRlYihoZG1pLCBIRE1JX1BIWV9EUklWRVIsIDB4MDApOwo+Pj4gKyAgICAgICAgaGRtaV93cml0 ZWIoaGRtaSwgSERNSV9QSFlfUFJFX0VNUEhBU0lTLCAweDAwKTsKPj4+ICsgICAgICAgIGhkbWlf d3JpdGViKGhkbWksIEhETUlfUEhZX0NIR19QV1IsIDB4MDApOwo+Pj4gKyAgICAgICAgaGRtaV93 cml0ZWIoaGRtaSwgSERNSV9QSFlfU1lTX0NUTCwgMHgxNSk7Cj4+PiArCj4+PiArICAgICAgICBi cmVhazsKPj4+ICsKPj4+ICsgICAgZGVmYXVsdDoKPj4+ICsgICAgICAgIGRldl9lcnIoaGRtaS0+ ZGV2LCAiVW5rbm93biBwb3dlciBtb2RlICVkXG4iLCBtb2RlKTsKPj4+ICsgICAgfQo+Pj4gK30K Pj4+ICsKPj4+ICtzdGF0aWMgdm9pZCBpbm5vX2hkbWlfcmVzZXQoc3RydWN0IGlubm9faGRtaSAq aGRtaSkKPj4+ICt7Cj4+PiArICAgIHUzMiB2YWw7Cj4+PiArICAgIHUzMiBtc2s7Cj4+PiArCj4+ PiArICAgIGhkbWlfbW9kYihoZG1pLCBIRE1JX1NZU19DVFJMLCBtX1JTVF9ESUdJVEFMLCB2X05P VF9SU1RfRElHSVRBTCk7Cj4+PiArICAgIHVkZWxheSgxMDApOwo+Pj4gKwo+Pj4gKyAgICBoZG1p X21vZGIoaGRtaSwgSERNSV9TWVNfQ1RSTCwgbV9SU1RfQU5BTE9HLCB2X05PVF9SU1RfQU5BTE9H KTsKPj4+ICsgICAgdWRlbGF5KDEwMCk7Cj4+PiArCj4+PiArICAgIG1zayA9IG1fUkVHX0NMS19J TlYgfCBtX1JFR19DTEtfU09VUkNFIHwgbV9QT1dFUiB8IG1fSU5UX1BPTDsKPj4+ICsgICAgdmFs ID0gdl9SRUdfQ0xLX0lOViB8IHZfUkVHX0NMS19TT1VSQ0VfU1lTIHwgdl9QV1JfT04gfCAKPj4+ IHZfSU5UX1BPTF9ISUdIOwo+Pj4gKyAgICBoZG1pX21vZGIoaGRtaSwgSERNSV9TWVNfQ1RSTCwg bXNrLCB2YWwpOwo+Pj4gKwo+Pj4gKyAgICBpbm5vX2hkbWlfc2V0X3B3cl9tb2RlKGhkbWksIE5P Uk1BTCk7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2NvbmZpZ192aWRl b19hdmkoc3RydWN0IGlubm9faGRtaSAqaGRtaSkKPj4+ICt7Cj4+PiArICAgIGNoYXIgaW5mb1tI RE1JX1NJWkVfQVZJX0lORk9GUkFNRV0gPSB7MH07Cj4+PiArICAgIGludCBhdmlfY29sb3JfbW9k ZTsKPj4+ICsgICAgaW50IGk7Cj4+PiArCj4+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlf Q09OVFJPTF9QQUNLRVRfQlVGX0lOREVYLCBJTkZPRlJBTUVfQVZJKTsKPj4+ICsKPj4+ICsgICAg aW5mb1swXSA9IDB4ODI7Cj4+PiArICAgIGluZm9bMV0gPSAweDAyOwo+Pj4gKyAgICBpbmZvWzJd ID0gMHgwRDsKPj4+ICsgICAgaW5mb1szXSA9IGluZm9bMF0gKyBpbmZvWzFdICsgaW5mb1syXTsK Pj4+ICsKPj4+ICsgICAgaWYgKGhkbWktPmhkbWlfZGF0YS5lbmNfb3V0X2Zvcm1hdCA9PSBIRE1J X0NPTE9SU1BBQ0VfUkdCKQo+Pj4gKyAgICAgICAgYXZpX2NvbG9yX21vZGUgPSBBVklfQ09MT1Jf TU9ERV9SR0I7Cj4+PiArICAgIGVsc2UgaWYgKGhkbWktPmhkbWlfZGF0YS5lbmNfb3V0X2Zvcm1h dCA9PSBIRE1JX0NPTE9SU1BBQ0VfWVVWNDQ0KQo+Pj4gKyAgICAgICAgYXZpX2NvbG9yX21vZGUg PSBBVklfQ09MT1JfTU9ERV9ZQ0JDUjQ0NDsKPj4+ICsgICAgZWxzZSBpZiAoaGRtaS0+aGRtaV9k YXRhLmVuY19vdXRfZm9ybWF0ID09IEhETUlfQ09MT1JTUEFDRV9ZVVY0MjIpCj4+PiArICAgICAg ICBhdmlfY29sb3JfbW9kZSA9IEFWSV9DT0xPUl9NT0RFX1lDQkNSNDIyOwo+Pj4gKyAgICBlbHNl Cj4+PiArICAgICAgICBhdmlfY29sb3JfbW9kZSA9IEFWSV9DT0xPUl9NT0RFX1JHQjsKPj4+ICsK Pj4+ICsgICAgaW5mb1s0XSA9IChhdmlfY29sb3JfbW9kZSA8PCA1KTsKPj4+ICsgICAgaW5mb1s1 XSA9IChBVklfQ09MT1JJTUVUUllfTk9fREFUQSA8PCA2KSB8Cj4+PiArICAgICAgICAgIChBVklf Q09ERURfRlJBTUVfQVNQRUNUX05PX0RBVEEgPDwgNCkgfAo+Pj4gKyAgICAgICAgICBBQ1RJVkVf QVNQRUNUX1JBVEVfU0FNRV9BU19DT0RFRF9GUkFNRTsKPj4+ICsKPj4+ICsgICAgaW5mb1s2XSA9 IDA7Cj4+PiArICAgIGluZm9bN10gPSBoZG1pLT5oZG1pX2RhdGEudmljOwo+Pj4gKwo+Pj4gKyAg ICBpZiAoaGRtaS0+aGRtaV9kYXRhLnZpYyA9PSA2IHx8IGhkbWktPmhkbWlfZGF0YS52aWMgPT0g NyB8fAo+Pj4gKyAgICAgICAgaGRtaS0+aGRtaV9kYXRhLnZpYyA9PSAyMSB8fCBoZG1pLT5oZG1p X2RhdGEudmljID09IDIyKQo+Pj4gKyAgICAgICAgaW5mb1s4XSA9IDE7Cj4+PiArICAgIGVsc2UK Pj4+ICsgICAgICAgIGluZm9bOF0gPSAwOwo+Pj4gKwo+Pj4gKyAgICAvKiBDYWxjdWxhdGUgYXZp IGluZm8gZnJhbWUgY2hlY0tzdW0gKi8KPj4+ICsgICAgZm9yIChpID0gNDsgaSA8IEhETUlfU0la RV9BVklfSU5GT0ZSQU1FOyBpKyspCj4+PiArICAgICAgICBpbmZvWzNdICs9IGluZm9baV07Cj4+ PiArICAgIGluZm9bM10gPSAweDEwMCAtIGluZm9bM107Cj4+PiArCj4+PiArICAgIGZvciAoaSA9 IDA7IGkgPCBIRE1JX1NJWkVfQVZJX0lORk9GUkFNRTsgaSsrKQo+Pj4gKyAgICAgICAgaGRtaV93 cml0ZWIoaGRtaSwgSERNSV9DT05UUk9MX1BBQ0tFVF9BRERSICsgaSwgaW5mb1tpXSk7Cj4+PiAr Cj4+PiArICAgIHJldHVybiAwOwo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMgaW50IGlubm9faGRt aV9jb25maWdfdmlkZW9fdnNpKHN0cnVjdCBpbm5vX2hkbWkgKmhkbWkpCj4+PiArewo+Pj4gKyAg ICBjaGFyIGluZm9bSERNSV9TSVpFX1ZTSV9JTkZPRlJBTUVdID0gezB9Owo+Pj4gKyAgICBpbnQg aTsKPj4+ICsKPj4+ICsgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfUEFDS0VUX1NFTkRfQVVUTywg bV9QQUNLRVRfVlNJX0VOLAo+Pj4gKyAgICAgICAgICB2X1BBQ0tFVF9WU0lfRU4oMCkpOwo+Pj4g Kwo+Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX0NPTlRST0xfUEFDS0VUX0JVRl9JTkRF WCwgSU5GT0ZSQU1FX1ZTSSk7Cj4+PiArCj4+PiArICAgIC8qIEhlYWRlciBCeXRlcyAqLwo+Pj4g KyAgICBpbmZvWzBdID0gMHg4MTsKPj4+ICsgICAgaW5mb1sxXSA9IDB4MDE7Cj4+PiArCj4+PiAr ICAgIC8qIFBCMSAtIFBCMyBjb250YWluIHRoZSAyNGJpdCBJRUVFIFJlZ2lzdHJhdGlvbiBJZGVu dGlmaWVyICovCj4+PiArICAgIGluZm9bNF0gPSAweDAzOwo+Pj4gKyAgICBpbmZvWzVdID0gMHgw YzsKPj4+ICsgICAgaW5mb1s2XSA9IDB4MDA7Cj4+PiArCj4+PiArICAgIC8qIFBCNCAtIEhETUlf VmlkZW9fRm9ybWF0IGludG8gYml0cyA3OjUgKi8KPj4+ICsgICAgaW5mb1s3XSA9IDA7Cj4+PiAr Cj4+PiArICAgIC8qCj4+PiArICAgICAqIFBCNSAtIERlcGVuZGluZyBvbiB0aGUgdmlkZW8gZm9y bWF0LCB0aGlzIGJ5dGUgd2lsbCBjb250YWluCj4+PiArICAgICAqIGVpdGhlciB0aGUgSERNSV9W SUMgY29kZSBpbiBidXRzIDc6MCwgT1IgdGhlIDNEX1N0cnVjdHVyZSBpbgo+Pj4gKyAgICAgKiBi aXRzIDc6NC4KPj4+ICsgICAgICovCj4+PiArICAgIGluZm9bMl0gPSAweDA2IC0gMjsKPj4+ICsg ICAgaW5mb1s4XSA9IDA7Cj4+PiArICAgIGluZm9bOV0gPSAwOwo+Pj4gKwo+Pj4gKyAgICBpbmZv WzNdID0gaW5mb1swXSArIGluZm9bMV0gKyBpbmZvWzJdOwo+Pj4gKwo+Pj4gKyAgICAvKiBDYWxj dWxhdGUgaW5mbyBmcmFtZSBjaGVjS3N1bSAqLwo+Pj4gKyAgICBmb3IgKGkgPSA0OyBpIDwgSERN SV9TSVpFX1ZTSV9JTkZPRlJBTUU7IGkrKykKPj4+ICsgICAgICAgIGluZm9bM10gKz0gaW5mb1tp XTsKPj4+ICsgICAgaW5mb1szXSA9IDB4MTAwIC0gaW5mb1szXTsKPj4+ICsKPj4+ICsgICAgZm9y IChpID0gMDsgaSA8IEhETUlfU0laRV9WU0lfSU5GT0ZSQU1FOyBpKyspCj4+PiArICAgICAgICBo ZG1pX3dyaXRlYihoZG1pLCBIRE1JX0NPTlRST0xfUEFDS0VUX0FERFIgKyBpLCBpbmZvW2ldKTsK Pj4+ICsKPj4+ICsgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfUEFDS0VUX1NFTkRfQVVUTywgbV9Q QUNLRVRfVlNJX0VOLAo+Pj4gKyAgICAgICAgICB2X1BBQ0tFVF9WU0lfRU4oMSkpOwo+Pj4gKwo+ Pj4gKyAgICByZXR1cm4gMDsKPj4+ICt9Cj4+PiArCj4+PiArc3RhdGljIGludCBpbm5vX2hkbWlf Y29uZmlnX3ZpZGVvX2NzYyhzdHJ1Y3QgaW5ub19oZG1pICpoZG1pKQo+Pj4gK3sKPj4+ICsgICAg c3RydWN0IGhkbWlfZGF0YV9pbmZvICpkYXRhID0gJmhkbWktPmhkbWlfZGF0YTsKPj4+ICsgICAg aW50IGMwX2MyX2NoYW5nZSA9IDA7Cj4+PiArICAgIGludCBjc2NfZW5hYmxlID0gMDsKPj4+ICsg ICAgaW50IGNzY19tb2RlID0gMDsKPj4+ICsgICAgaW50IGF1dG9fY3NjID0gMDsKPj4+ICsgICAg aW50IHZhbHVlOwo+Pj4gKyAgICBpbnQgaTsKPj4+ICsKPj4+ICsgICAgLyogSW5wdXQgdmlkZW8g bW9kZSBpcyBTRFIgUkdCMjRiaXQsIGRhdGEgZW5hYmxlIHNpZ25hbCBmcm9tIAo+Pj4gZXh0ZXJu YWwgKi8KPj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19DT05UUkwxLCB2X0RF X0VYVEVSTkFMIHwKPj4+ICsgICAgICAgICAgICB2X1ZJREVPX0lOUFVUX0ZPUk1BVChWSURFT19J TlBVVF9TRFJfUkdCNDQ0KSk7Cj4+PiArCj4+PiArICAgIC8qIElucHV0IGNvbG9yIGhhcmRjb2Rl IHRvIFJHQiwgYW5kIG91dHB1dCBjb2xvciBoYXJkY29kZSB0byAKPj4+IFJHQjg4OCAqLwo+Pj4g KyAgICB2YWx1ZSA9IHZfVklERU9fSU5QVVRfQklUUyhWSURFT19JTlBVVF84QklUUykgfAo+Pj4g KyAgICAgICAgdl9WSURFT19PVVRQVVRfQ09MT1IoMCkgfAo+Pj4gKyAgICAgICAgdl9WSURFT19J TlBVVF9DU1AoMCk7Cj4+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfVklERU9fQ09OVFJM MiwgdmFsdWUpOwo+Pj4gKwo+Pj4gKyAgICBpZiAoZGF0YS0+ZW5jX291dF9mb3JtYXQgPT0gZGF0 YS0+ZW5jX291dF9mb3JtYXQpIHsKPj4+ICsgICAgICAgIGlmICgoZGF0YS0+ZW5jX2luX2Zvcm1h dCA9PSBIRE1JX0NPTE9SU1BBQ0VfUkdCKSB8fAo+Pj4gKyAgICAgICAgICAgIChkYXRhLT5lbmNf aW5fZm9ybWF0ID49IEhETUlfQ09MT1JTUEFDRV9ZVVY0NDQpKSB7Cj4+PiArICAgICAgICAgICAg dmFsdWUgPSB2X1NPRl9ESVNBQkxFIHwgdl9DT0xPUl9ERVBUSF9OT1RfSU5ESUNBVEVEKDEpOwo+ Pj4gKyAgICAgICAgICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfVklERU9fQ09OVFJMMywgdmFs dWUpOwo+Pj4gKwo+Pj4gKyAgICAgICAgICAgIGhkbWlfbW9kYihoZG1pLCBIRE1JX1ZJREVPX0NP TlRSTCwKPj4+ICsgICAgICAgICAgICAgICAgICBtX1ZJREVPX0FVVE9fQ1NDIHwgbV9WSURFT19D MF9DMl9TV0FQLAo+Pj4gKyAgICAgICAgICAgICAgICAgIHZfVklERU9fQVVUT19DU0MoQVVUT19D U0NfRElTQUJMRSkgfAo+Pj4gKyAgICAgICAgICAgICAgICAgIHZfVklERU9fQzBfQzJfU1dBUChD MF9DMl9DSEFOR0VfRElTQUJMRSkpOwo+Pj4gKyAgICAgICAgICAgIHJldHVybiAwOwo+Pj4gKyAg ICAgICAgfQo+Pj4gKyAgICB9Cj4+PiArCj4+PiArICAgIGlmIChkYXRhLT5jb2xvcmltZXRyeSA9 PSBIRE1JX0NPTE9SSU1FVFJZX0lUVV82MDEpIHsKPj4+ICsgICAgICAgIGlmICgoZGF0YS0+ZW5j X2luX2Zvcm1hdCA9PSBIRE1JX0NPTE9SU1BBQ0VfUkdCKSAmJgo+Pj4gKyAgICAgICAgICAgIChk YXRhLT5lbmNfb3V0X2Zvcm1hdCA9PSBIRE1JX0NPTE9SU1BBQ0VfWVVWNDQ0KSkgewo+Pj4gKyAg ICAgICAgICAgIGNzY19tb2RlID0gQ1NDX1JHQl8wXzI1NV9UT19JVFU2MDFfMTZfMjM1XzhCSVQ7 Cj4+PiArICAgICAgICAgICAgYXV0b19jc2MgPSBBVVRPX0NTQ19ESVNBQkxFOwo+Pj4gKyAgICAg ICAgICAgIGMwX2MyX2NoYW5nZSA9IEMwX0MyX0NIQU5HRV9ESVNBQkxFOwo+Pj4gKyAgICAgICAg ICAgIGNzY19lbmFibGUgPSB2X0NTQ19FTkFCTEU7Cj4+PiArICAgICAgICB9IGVsc2UgaWYgKChk YXRhLT5lbmNfaW5fZm9ybWF0ID09IEhETUlfQ09MT1JTUEFDRV9ZVVY0NDQpICYmCj4+PiArICAg ICAgICAgICAgICAgKGRhdGEtPmVuY19vdXRfZm9ybWF0ID09IEhETUlfQ09MT1JTUEFDRV9SR0Ip KSB7Cj4+PiArICAgICAgICAgICAgY3NjX21vZGUgPSBDU0NfSVRVNjAxXzE2XzIzNV9UT19SR0Jf MF8yNTVfOEJJVDsKPj4+ICsgICAgICAgICAgICBhdXRvX2NzYyA9IEFVVE9fQ1NDX0VOQUJMRTsK Pj4+ICsgICAgICAgICAgICBjMF9jMl9jaGFuZ2UgPSBDMF9DMl9DSEFOR0VfRElTQUJMRTsKPj4+ ICsgICAgICAgICAgICBjc2NfZW5hYmxlID0gdl9DU0NfRElTQUJMRTsKPj4+ICsgICAgICAgIH0K Pj4+ICsgICAgfSBlbHNlIHsKPj4+ICsgICAgICAgIGlmICgoZGF0YS0+ZW5jX2luX2Zvcm1hdCA9 PSBIRE1JX0NPTE9SU1BBQ0VfUkdCKSAmJgo+Pj4gKyAgICAgICAgICAgIChkYXRhLT5lbmNfb3V0 X2Zvcm1hdCA9PSBIRE1JX0NPTE9SU1BBQ0VfWVVWNDQ0KSkgewo+Pj4gKyAgICAgICAgICAgIGNz Y19tb2RlID0gQ1NDX1JHQl8wXzI1NV9UT19JVFU3MDlfMTZfMjM1XzhCSVQ7Cj4+PiArICAgICAg ICAgICAgYXV0b19jc2MgPSBBVVRPX0NTQ19ESVNBQkxFOwo+Pj4gKyAgICAgICAgICAgIGMwX2My X2NoYW5nZSA9IEMwX0MyX0NIQU5HRV9ESVNBQkxFOwo+Pj4gKyAgICAgICAgICAgIGNzY19lbmFi bGUgPSB2X0NTQ19FTkFCTEU7Cj4+PiArICAgICAgICB9IGVsc2UgaWYgKChkYXRhLT5lbmNfaW5f Zm9ybWF0ID09IEhETUlfQ09MT1JTUEFDRV9ZVVY0NDQpICYmCj4+PiArICAgICAgICAgICAgICAg KGRhdGEtPmVuY19vdXRfZm9ybWF0ID09IEhETUlfQ09MT1JTUEFDRV9SR0IpKSB7Cj4+PiArICAg ICAgICAgICAgY3NjX21vZGUgPSBDU0NfSVRVNzA5XzE2XzIzNV9UT19SR0JfMF8yNTVfOEJJVDsK Pj4+ICsgICAgICAgICAgICBhdXRvX2NzYyA9IEFVVE9fQ1NDX0VOQUJMRTsKPj4+ICsgICAgICAg ICAgICBjMF9jMl9jaGFuZ2UgPSBDMF9DMl9DSEFOR0VfRElTQUJMRTsKPj4+ICsgICAgICAgICAg ICBjc2NfZW5hYmxlID0gdl9DU0NfRElTQUJMRTsKPj4+ICsgICAgICAgIH0KPj4+ICsgICAgfQo+ Pj4gKwo+Pj4gKyAgICBmb3IgKGkgPSAwOyBpIDwgMjQ7IGkrKykKPj4+ICsgICAgICAgIGhkbWlf d3JpdGViKGhkbWksIEhETUlfVklERU9fQ1NDX0NPRUYgKyBpLAo+Pj4gKyAgICAgICAgICAgICAg ICBjb2VmZl9jc2NbY3NjX21vZGVdW2ldKTsKPj4+ICsKPj4+ICsgICAgdmFsdWUgPSB2X1NPRl9E SVNBQkxFIHwgY3NjX2VuYWJsZSB8IAo+Pj4gdl9DT0xPUl9ERVBUSF9OT1RfSU5ESUNBVEVEKDEp Owo+Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0NPTlRSTDMsIHZhbHVlKTsK Pj4+ICsgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfVklERU9fQ09OVFJMLCBtX1ZJREVPX0FVVE9f Q1NDIHwKPj4+ICsgICAgICAgICAgbV9WSURFT19DMF9DMl9TV0FQLCB2X1ZJREVPX0FVVE9fQ1ND KGF1dG9fY3NjKSB8Cj4+PiArICAgICAgICAgIHZfVklERU9fQzBfQzJfU1dBUChjMF9jMl9jaGFu Z2UpKTsKPj4+ICsKPj4+ICsgICAgcmV0dXJuIDA7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyBp bnQgaW5ub19oZG1pX2NvbmZpZ192aWRlb190aW1pbmcoc3RydWN0IGlubm9faGRtaSAqaGRtaSwK Pj4+ICsgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSkK Pj4+ICt7Cj4+PiArICAgIGludCB2YWx1ZTsKPj4+ICsKPj4+ICsgICAgLyogU2V0IGRldGFpbCBl eHRlcm5hbCB2aWRlbyB0aW1pbmcgcG9sYXJpdHkgYW5kIGludGVybGFjZSBtb2RlICovCj4+PiAr ICAgIHZhbHVlID0gdl9FWFRFUkFOTF9WSURFTygxKTsKPj4+ICsgICAgdmFsdWUgfD0gbW9kZS0+ ZmxhZ3MgJiBEUk1fTU9ERV9GTEFHX1BIU1lOQyA/Cj4+PiArICAgICAgICAgdl9IU1lOQ19QT0xB UklUWSgxKSA6IHZfSFNZTkNfUE9MQVJJVFkoMCk7Cj4+PiArICAgIHZhbHVlIHw9IG1vZGUtPmZs YWdzICYgRFJNX01PREVfRkxBR19QVlNZTkMgPwo+Pj4gKyAgICAgICAgIHZfVlNZTkNfUE9MQVJJ VFkoMSkgOiB2X1ZTWU5DX1BPTEFSSVRZKDApOwo+Pj4gKyAgICB2YWx1ZSB8PSBtb2RlLT5mbGFn cyAmIERSTV9NT0RFX0ZMQUdfSU5URVJMQUNFID8KPj4+ICsgICAgICAgICB2X0lORVRMQUNFKDEp IDogdl9JTkVUTEFDRSgwKTsKPj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19U SU1JTkdfQ1RMLCB2YWx1ZSk7Cj4+PiArCj4+PiArICAgIC8qIFNldCBkZXRhaWwgZXh0ZXJuYWwg dmlkZW8gdGltaW5nICovCj4+PiArICAgIHZhbHVlID0gbW9kZS0+aHRvdGFsOwo+Pj4gKyAgICBo ZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0VYVF9IVE9UQUxfTCwgdmFsdWUgJiAweEZGKTsK Pj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19FWFRfSFRPVEFMX0gsICh2YWx1 ZSA+PiA4KSAmIDB4RkYpOwo+Pj4gKwo+Pj4gKyAgICB2YWx1ZSA9IG1vZGUtPmh0b3RhbCAtIG1v ZGUtPmhkaXNwbGF5Owo+Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0VYVF9I QkxBTktfTCwgdmFsdWUgJiAweEZGKTsKPj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9W SURFT19FWFRfSEJMQU5LX0gsICh2YWx1ZSA+PiA4KSAmIDB4RkYpOwo+Pj4gKwo+Pj4gKyAgICB2 YWx1ZSA9IG1vZGUtPmhzeW5jX3N0YXJ0IC0gbW9kZS0+aGRpc3BsYXk7Cj4+PiArICAgIGhkbWlf d3JpdGViKGhkbWksIEhETUlfVklERU9fRVhUX0hERUxBWV9MLCB2YWx1ZSAmIDB4RkYpOwo+Pj4g KyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0VYVF9IREVMQVlfSCwgKHZhbHVlID4+ IDgpICYgMHhGRik7Cj4+PiArCj4+PiArICAgIHZhbHVlID0gbW9kZS0+aHN5bmNfZW5kIC0gbW9k ZS0+aHN5bmNfc3RhcnQ7Cj4+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfVklERU9fRVhU X0hEVVJBVElPTl9MLCB2YWx1ZSAmIDB4RkYpOwo+Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBI RE1JX1ZJREVPX0VYVF9IRFVSQVRJT05fSCwgKHZhbHVlID4+IDgpICYgCj4+PiAweEZGKTsKPj4+ ICsKPj4+ICsgICAgdmFsdWUgPSBtb2RlLT52dG90YWw7Cj4+PiArICAgIGhkbWlfd3JpdGViKGhk bWksIEhETUlfVklERU9fRVhUX1ZUT1RBTF9MLCB2YWx1ZSAmIDB4RkYpOwo+Pj4gKyAgICBoZG1p X3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0VYVF9WVE9UQUxfSCwgKHZhbHVlID4+IDgpICYgMHhG Rik7Cj4+PiArCj4+PiArICAgIHZhbHVlID0gbW9kZS0+dnRvdGFsIC0gbW9kZS0+dmRpc3BsYXk7 Cj4+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfVklERU9fRVhUX1ZCTEFOSywgdmFsdWUg JiAweEZGKTsKPj4+ICsKPj4+ICsgICAgdmFsdWUgPSBtb2RlLT52c3luY19zdGFydCAtIG1vZGUt PnZkaXNwbGF5Owo+Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0VYVF9WREVM QVksIHZhbHVlICYgMHhGRik7Cj4+PiArCj4+PiArICAgIHZhbHVlID0gbW9kZS0+dnN5bmNfZW5k IC0gbW9kZS0+dnN5bmNfc3RhcnQ7Cj4+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfVklE RU9fRVhUX1ZEVVJBVElPTiwgdmFsdWUgJiAweEZGKTsKPj4+ICsKPj4+ICsgICAgaGRtaV93cml0 ZWIoaGRtaSwgSERNSV9QSFlfUFJFX0RJVl9SQVRJTywgMHgxZSk7Cj4+PiArICAgIGhkbWlfd3Jp dGViKGhkbWksIEhETUlfUEhZX0ZFRURCQUNLX0RJVl9SQVRJT19MT1csIDB4MmMpOwo+Pj4gKyAg ICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1BIWV9GRUVEQkFDS19ESVZfUkFUSU9fSElHSCwgMHgw MSk7Cj4+PiArCj4+PiArICAgIHJldHVybiAwOwo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMgaW50 IGlubm9faGRtaV9zZXR1cChzdHJ1Y3QgaW5ub19oZG1pICpoZG1pLAo+Pj4gKyAgICAgICAgICAg ICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlKQo+Pj4gK3sKPj4+ICsgICAgaW50IHZh bHVlOwo+Cj4gV2hlcmUgYmUgdXNlZD8KPiBJIGd1ZXNzIHlvdSBzaG91bGQgcmVtb3ZlIGl0Lgo+ Cj4KPgo+IC0KPiBDYWVzYXIKPj4+ICsKPj4+ICsgICAgaGRtaS0+aGRtaV9kYXRhLnZpYyA9IGRy bV9tYXRjaF9jZWFfbW9kZShtb2RlKTsKPj4+ICsKPj4+ICsgICAgaGRtaS0+aGRtaV9kYXRhLmVu Y19pbl9mb3JtYXQgPSBIRE1JX0NPTE9SU1BBQ0VfUkdCOwo+Pj4gKyAgICBoZG1pLT5oZG1pX2Rh dGEuZW5jX291dF9mb3JtYXQgPSBIRE1JX0NPTE9SU1BBQ0VfUkdCOwo+Pj4gKwo+Pj4gKyAgICBp ZiAoKGhkbWktPmhkbWlfZGF0YS52aWMgPT0gNikgfHwgKGhkbWktPmhkbWlfZGF0YS52aWMgPT0g NykgfHwKPj4+ICsgICAgICAgIChoZG1pLT5oZG1pX2RhdGEudmljID09IDIxKSB8fCAoaGRtaS0+ aGRtaV9kYXRhLnZpYyA9PSAyMikgfHwKPj4+ICsgICAgICAgIChoZG1pLT5oZG1pX2RhdGEudmlj ID09IDIpIHx8IChoZG1pLT5oZG1pX2RhdGEudmljID09IDMpIHx8Cj4+PiArICAgICAgICAoaGRt aS0+aGRtaV9kYXRhLnZpYyA9PSAxNykgfHwgKGhkbWktPmhkbWlfZGF0YS52aWMgPT0gMTgpKQo+ Pj4gKyAgICAgICAgaGRtaS0+aGRtaV9kYXRhLmNvbG9yaW1ldHJ5ID0gSERNSV9DT0xPUklNRVRS WV9JVFVfNjAxOwo+Pj4gKyAgICBlbHNlCj4+PiArICAgICAgICBoZG1pLT5oZG1pX2RhdGEuY29s b3JpbWV0cnkgPSBIRE1JX0NPTE9SSU1FVFJZX0lUVV83MDk7Cj4+PiArCj4+PiArICAgIC8qIE11 dGUgdmlkZW8gYW5kIGF1ZGlvIG91dHB1dCAqLwo+Pj4gKyAgICBoZG1pX21vZGIoaGRtaSwgSERN SV9BVl9NVVRFLCBtX0FVRElPX01VVEUgfCBtX1ZJREVPX0JMQUNLLAo+Pj4gKyAgICAgICAgICB2 X0FVRElPX01VVEUoMSkgfCB2X1ZJREVPX01VVEUoMSkpOwo+Pj4gKwo+Pj4gKyAgICAvKiBTZXQg SERNSSBNb2RlICovCj4+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfSERDUF9DVFJMLAo+ Pj4gKyAgICAgICAgICAgIHZfSERNSV9EVkkoaGRtaS0+aGRtaV9kYXRhLnNpbmtfaXNfaGRtaSkp Owo+Pj4gKwo+Pj4gKyAgICBpbm5vX2hkbWlfY29uZmlnX3ZpZGVvX3RpbWluZyhoZG1pLCBtb2Rl KTsKPj4+ICsKPj4+ICsgICAgaW5ub19oZG1pX2NvbmZpZ192aWRlb19jc2MoaGRtaSk7Cj4+PiAr Cj4+PiArICAgIGlmIChoZG1pLT5oZG1pX2RhdGEuc2lua19pc19oZG1pKSB7Cj4+PiArICAgICAg ICBpbm5vX2hkbWlfY29uZmlnX3ZpZGVvX2F2aShoZG1pKTsKPj4+ICsgICAgICAgIGlubm9faGRt aV9jb25maWdfdmlkZW9fdnNpKGhkbWkpOwo+Pj4gKyAgICB9Cj4+PiArCj4+PiArICAgIC8qCj4+ PiArICAgICAqIFdoZW4gSVAgY29udHJvbGxlciBoYXZlIGNvbmZpZ3VyZWQgdG8gYW4gYWNjdXJh dGUgdmlkZW8KPj4+ICsgICAgICogdGltaW5nLCB0aGVuIHRoZSBUTURTIGNsb2NrIHNvdXJjZSB3 b3VsZCBiZSBzd2l0Y2hlZCB0bwo+Pj4gKyAgICAgKiBEQ0xLX0xDREMsIHNvIHdlIG5lZWQgdG8g aW5pdCB0aGUgVE1EUyByYXRlIHRvIG1vZGUgcGl4ZWwKPj4+ICsgICAgICogY2xvY2sgcmF0ZSwg YW5kIHJlY29uZmlndXJlIHRoZSBEREMgY2xvY2suCj4+PiArICAgICAqLwo+Pj4gKyAgICBoZG1p LT50bWRzX3JhdGUgPSBtb2RlLT5jbG9jayAqIDEwMDA7Cj4+PiArICAgIGlubm9faGRtaV9pMmNf aW5pdChoZG1pKTsKPj4+ICsKPj4+ICsgICAgLyogVW5tdXRlIHZpZGVvIGFuZCBhdWRpbyBvdXRw dXQgKi8KPj4+ICsgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfQVZfTVVURSwgbV9BVURJT19NVVRF IHwgbV9WSURFT19CTEFDSywKPj4+ICsgICAgICAgICAgdl9BVURJT19NVVRFKDApIHwgdl9WSURF T19NVVRFKDApKTsKPj4+ICsKPj4+ICsgICAgcmV0dXJuIDA7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0 YXRpYyB2b2lkIGlubm9faGRtaV9lbmNvZGVyX21vZGVfc2V0KHN0cnVjdCBkcm1fZW5jb2RlciAq ZW5jb2RlciwKPj4+ICsgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkcm1fZGlzcGxheV9t b2RlICptb2RlLAo+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRybV9kaXNwbGF5 X21vZGUgKmFkal9tb2RlKQo+Pj4gK3sKPj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRtaSA9 IHRvX2lubm9faGRtaShlbmNvZGVyKTsKPj4+ICsKPj4+ICsgICAgaW5ub19oZG1pX3NldHVwKGhk bWksIGFkal9tb2RlKTsKPj4+ICsKPj4+ICsgICAgLyogU3RvcmUgdGhlIGRpc3BsYXkgbW9kZSBm b3IgcGx1Z2luL0RLTVMgcG93ZXJvbiBldmVudHMgKi8KPj4KPj4gSSB0aGluayBES01TIHNob3Vs ZCBiZSBEUE1TLgo+Pgo+Pj4gKyAgICBtZW1jcHkoJmhkbWktPnByZXZpb3VzX21vZGUsIGFkal9t b2RlLCAKPj4+IHNpemVvZihoZG1pLT5wcmV2aW91c19tb2RlKSk7Cj4+PiArfQo+Pj4gKwo+Pj4g K3N0YXRpYyB2b2lkIGlubm9faGRtaV9lbmNvZGVyX2VuYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIg KmVuY29kZXIpCj4+PiArewo+Pj4gKyAgICBzdHJ1Y3QgaW5ub19oZG1pICpoZG1pID0gdG9faW5u b19oZG1pKGVuY29kZXIpOwo+Pj4gKwo+Pj4gKyAgICBpbm5vX2hkbWlfc2V0X3B3cl9tb2RlKGhk bWksIE5PUk1BTCk7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyB2b2lkIGlubm9faGRtaV9lbmNv ZGVyX2Rpc2FibGUoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyKQo+Pj4gK3sKPj4+ICsgICAg c3RydWN0IGlubm9faGRtaSAqaGRtaSA9IHRvX2lubm9faGRtaShlbmNvZGVyKTsKPj4+ICsKPj4+ ICsgICAgaW5ub19oZG1pX3NldF9wd3JfbW9kZShoZG1pLCBMT1dFUl9QV1IpOwo+Pj4gK30KPj4+ ICsKPj4+ICtzdGF0aWMgdm9pZCBpbm5vX2hkbWlfZW5jb2Rlcl9jb21taXQoc3RydWN0IGRybV9l bmNvZGVyICplbmNvZGVyKQo+Pj4gK3sKPj4+ICt9Cj4+PiArCj4+PiArc3RhdGljIHZvaWQgaW5u b19oZG1pX2VuY29kZXJfcHJlcGFyZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCj4+PiAr ewo+Pj4gKyAgICByb2NrY2hpcF9kcm1fY3J0Y19tb2RlX2NvbmZpZyhlbmNvZGVyLT5jcnRjLCAK Pj4+IERSTV9NT0RFX0NPTk5FQ1RPUl9IRE1JQSwKPj4+ICsgICAgICAgICAgICAgICAgICAgICAg Uk9DS0NISVBfT1VUX01PREVfUDg4OCk7Cj4+Cj4+IENhbiB5b3UgbW92ZSBtb2RlX2NvbmZpZyBp bnRvIGlubm9faGRtaV9lbmNvZGVyX2VuYWJsZSwgYW5kIHJlbW92ZSAKPj4gLnByZXBhcmUgYW5k IC5jb21taXQ/Cj4+Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyBib29sIGlubm9faGRtaV9lbmNv ZGVyX21vZGVfZml4dXAoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyLAo+Pj4gKyAgICAgICAg ICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlLAo+Pj4gKyAg ICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICphZGpfbW9kZSkKPj4+ ICt7Cj4+PiArICAgIHJldHVybiB0cnVlOwo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMgc3RydWN0 IGRybV9lbmNvZGVyX2hlbHBlcl9mdW5jcyAKPj4+IGlubm9faGRtaV9lbmNvZGVyX2hlbHBlcl9m dW5jcyA9IHsKPj4+ICsgICAgLmVuYWJsZSAgICAgPSBpbm5vX2hkbWlfZW5jb2Rlcl9lbmFibGUs Cj4+PiArICAgIC5kaXNhYmxlICAgID0gaW5ub19oZG1pX2VuY29kZXJfZGlzYWJsZSwKPj4+ICsg ICAgLm1vZGVfZml4dXAgPSBpbm5vX2hkbWlfZW5jb2Rlcl9tb2RlX2ZpeHVwLAo+Pj4gKyAgICAu bW9kZV9zZXQgICA9IGlubm9faGRtaV9lbmNvZGVyX21vZGVfc2V0LAo+Pj4gKyAgICAucHJlcGFy ZSAgICA9IGlubm9faGRtaV9lbmNvZGVyX3ByZXBhcmUsCj4+PiArICAgIC5jb21taXQgICAgID0g aW5ub19oZG1pX2VuY29kZXJfY29tbWl0LAo+Pgo+PiBPbiBkcm0gYXRvbWljLCBJIHRoaW5rIGlm IHN1cHBvcnQgLmVuYWJsZSBhbmQgLmRpc2FibGUgY2FsbGJhY2tzLCAKPj4gdGhlbiAucHJlcGFy ZSBhbmQgLmNvbW1pdCBpcyBub3QgbmVlZGVkLgo+Pgo+Pj4gK307Cj4+PiArCj4+PiArc3RhdGlj IHN0cnVjdCBkcm1fZW5jb2Rlcl9mdW5jcyBpbm5vX2hkbWlfZW5jb2Rlcl9mdW5jcyA9IHsKPj4+ ICsgICAgLmRlc3Ryb3kgPSBkcm1fZW5jb2Rlcl9jbGVhbnVwLAo+Pj4gK307Cj4+PiArCj4+PiAr c3RhdGljIGVudW0gZHJtX2Nvbm5lY3Rvcl9zdGF0dXMKPj4+ICtpbm5vX2hkbWlfY29ubmVjdG9y X2RldGVjdChzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yLCBib29sIAo+Pj4gZm9yY2Up Cj4+PiArewo+Pj4gKyAgICBzdHJ1Y3QgaW5ub19oZG1pICpoZG1pID0gdG9faW5ub19oZG1pKGNv bm5lY3Rvcik7Cj4+PiArCj4+PiArICAgIHJldHVybiAoaGRtaV9yZWFkYihoZG1pLCBIRE1JX1NU QVRVUykgJiBtX0hPVFBMVUcpID8KPj4+ICsgICAgICAgIGNvbm5lY3Rvcl9zdGF0dXNfY29ubmVj dGVkIDogY29ubmVjdG9yX3N0YXR1c19kaXNjb25uZWN0ZWQ7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0 YXRpYyBpbnQgaW5ub19oZG1pX2Nvbm5lY3Rvcl9nZXRfbW9kZXMoc3RydWN0IGRybV9jb25uZWN0 b3IgCj4+PiAqY29ubmVjdG9yKQo+Pj4gK3sKPj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRt aSA9IHRvX2lubm9faGRtaShjb25uZWN0b3IpOwo+Pj4gKyAgICBzdHJ1Y3QgZWRpZCAqZWRpZDsK Pj4+ICsgICAgaW50IHJldCA9IDA7Cj4+PiArCj4+PiArICAgIGlmICghaGRtaS0+ZGRjKQo+Pj4g KyAgICAgICAgcmV0dXJuIDA7Cj4+PiArCj4+PiArICAgIGVkaWQgPSBkcm1fZ2V0X2VkaWQoY29u bmVjdG9yLCBoZG1pLT5kZGMpOwo+Pj4gKyAgICBpZiAoZWRpZCkgewo+Pj4gKyAgICAgICAgaGRt aS0+aGRtaV9kYXRhLnNpbmtfaXNfaGRtaSA9IGRybV9kZXRlY3RfaGRtaV9tb25pdG9yKGVkaWQp Owo+Pj4gKyAgICAgICAgaGRtaS0+aGRtaV9kYXRhLnNpbmtfaGFzX2F1ZGlvID0gCj4+PiBkcm1f ZGV0ZWN0X21vbml0b3JfYXVkaW8oZWRpZCk7Cj4+PiArICAgICAgICBkcm1fbW9kZV9jb25uZWN0 b3JfdXBkYXRlX2VkaWRfcHJvcGVydHkoY29ubmVjdG9yLCBlZGlkKTsKPj4+ICsgICAgICAgIHJl dCA9IGRybV9hZGRfZWRpZF9tb2Rlcyhjb25uZWN0b3IsIGVkaWQpOwo+Pj4gKyAgICAgICAga2Zy ZWUoZWRpZCk7Cj4+PiArICAgIH0KPj4+ICsKPj4+ICsgICAgcmV0dXJuIHJldDsKPj4+ICt9Cj4+ PiArCj4+PiArc3RhdGljIGVudW0gZHJtX21vZGVfc3RhdHVzCj4+PiAraW5ub19oZG1pX2Nvbm5l Y3Rvcl9tb2RlX3ZhbGlkKHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3IsCj4+PiArICAg ICAgICAgICAgICAgICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlKQo+Pj4gK3sKPj4+ ICsgICAgcmV0dXJuIE1PREVfT0s7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyBzdHJ1Y3QgZHJt X2VuY29kZXIgKgo+Pj4gK2lubm9faGRtaV9jb25uZWN0b3JfYmVzdF9lbmNvZGVyKHN0cnVjdCBk cm1fY29ubmVjdG9yICpjb25uZWN0b3IpCj4+PiArewo+Pj4gKyAgICBzdHJ1Y3QgaW5ub19oZG1p ICpoZG1pID0gdG9faW5ub19oZG1pKGNvbm5lY3Rvcik7Cj4+PiArCj4+PiArICAgIHJldHVybiAm aGRtaS0+ZW5jb2RlcjsKPj4+ICt9Cj4+PiArCj4+PiArc3RhdGljIGludAo+Pj4gK2lubm9faGRt aV9wcm9iZV9zaW5nbGVfY29ubmVjdG9yX21vZGVzKHN0cnVjdCBkcm1fY29ubmVjdG9yIAo+Pj4g KmNvbm5lY3RvciwKPj4+ICsgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IG1heFgsIHVp bnQzMl90IG1heFkpCj4+PiArewo+Pj4gKyAgICByZXR1cm4gZHJtX2hlbHBlcl9wcm9iZV9zaW5n bGVfY29ubmVjdG9yX21vZGVzKGNvbm5lY3RvciwgMTkyMCwgCj4+PiAxMDgwKTsKPj4+ICt9Cj4+ PiArCj4+PiArc3RhdGljIHZvaWQgaW5ub19oZG1pX2Nvbm5lY3Rvcl9kZXN0cm95KHN0cnVjdCBk cm1fY29ubmVjdG9yIAo+Pj4gKmNvbm5lY3RvcikKPj4+ICt7Cj4+PiArICAgIGRybV9jb25uZWN0 b3JfdW5yZWdpc3Rlcihjb25uZWN0b3IpOwo+Pj4gKyAgICBkcm1fY29ubmVjdG9yX2NsZWFudXAo Y29ubmVjdG9yKTsKPj4+ICt9Cj4+PiArCj4+PiArc3RhdGljIHN0cnVjdCBkcm1fY29ubmVjdG9y X2Z1bmNzIGlubm9faGRtaV9jb25uZWN0b3JfZnVuY3MgPSB7Cj4+PiArICAgIC5kcG1zID0gZHJt X2F0b21pY19oZWxwZXJfY29ubmVjdG9yX2RwbXMsCj4+PiArICAgIC5maWxsX21vZGVzID0gaW5u b19oZG1pX3Byb2JlX3NpbmdsZV9jb25uZWN0b3JfbW9kZXMsCj4+PiArICAgIC5kZXRlY3QgPSBp bm5vX2hkbWlfY29ubmVjdG9yX2RldGVjdCwKPj4+ICsgICAgLmRlc3Ryb3kgPSBpbm5vX2hkbWlf Y29ubmVjdG9yX2Rlc3Ryb3ksCj4+PiArICAgIC5yZXNldCA9IGRybV9hdG9taWNfaGVscGVyX2Nv bm5lY3Rvcl9yZXNldCwKPj4+ICsgICAgLmF0b21pY19kdXBsaWNhdGVfc3RhdGUgPSAKPj4+IGRy bV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kdXBsaWNhdGVfc3RhdGUsCj4+PiArICAgIC5hdG9t aWNfZGVzdHJveV9zdGF0ZSA9IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kZXN0cm95X3N0 YXRlLAo+Pj4gK307Cj4+PiArCj4+PiArc3RhdGljIHN0cnVjdCBkcm1fY29ubmVjdG9yX2hlbHBl cl9mdW5jcyAKPj4+IGlubm9faGRtaV9jb25uZWN0b3JfaGVscGVyX2Z1bmNzID0gewo+Pj4gKyAg ICAuZ2V0X21vZGVzID0gaW5ub19oZG1pX2Nvbm5lY3Rvcl9nZXRfbW9kZXMsCj4+PiArICAgIC5t b2RlX3ZhbGlkID0gaW5ub19oZG1pX2Nvbm5lY3Rvcl9tb2RlX3ZhbGlkLAo+Pj4gKyAgICAuYmVz dF9lbmNvZGVyID0gaW5ub19oZG1pX2Nvbm5lY3Rvcl9iZXN0X2VuY29kZXIsCj4+PiArfTsKPj4+ ICsKPj4+ICtzdGF0aWMgaW50IGlubm9faGRtaV9yZWdpc3RlcihzdHJ1Y3QgZHJtX2RldmljZSAq ZHJtLCBzdHJ1Y3QgCj4+PiBpbm5vX2hkbWkgKmhkbWkpCj4+PiArewo+Pj4gKyAgICBzdHJ1Y3Qg ZHJtX2VuY29kZXIgKmVuY29kZXIgPSAmaGRtaS0+ZW5jb2RlcjsKPj4+ICsKPj4+ICsgICAgZW5j b2Rlci0+cG9zc2libGVfY3J0Y3MgPSBkcm1fb2ZfZmluZF9wb3NzaWJsZV9jcnRjcyhkcm0sIAo+ Pj4gaGRtaS0+ZGV2LT5vZl9ub2RlKTsKPj4KPj4gS2VlcCA4MCBjaGFyYWN0ZXJzIDotKSAuCj4+ Cj4+PiArICAgIC8qCj4+PiArICAgICAqIElmIHdlIGZhaWxlZCB0byBmaW5kIHRoZSBDUlRDKHMp IHdoaWNoIHRoaXMgZW5jb2RlciBpcwo+Pj4gKyAgICAgKiBzdXBwb3NlZCB0byBiZSBjb25uZWN0 ZWQgdG8sIGl0J3MgYmVjYXVzZSB0aGUgQ1JUQyBoYXMKPj4+ICsgICAgICogbm90IGJlZW4gcmVn aXN0ZXJlZCB5ZXQuICBEZWZlciBwcm9iaW5nLCBhbmQgaG9wZSB0aGF0Cj4+PiArICAgICAqIHRo ZSByZXF1aXJlZCBDUlRDIGlzIGFkZGVkIGxhdGVyLgo+Pj4gKyAgICAgKi8KPj4+ICsgICAgaWYg KGVuY29kZXItPnBvc3NpYmxlX2NydGNzID09IDApCj4+PiArICAgICAgICByZXR1cm4gLUVQUk9C RV9ERUZFUjsKPj4+ICsKPj4+ICsgICAgZHJtX2VuY29kZXJfaGVscGVyX2FkZChlbmNvZGVyLCAm aW5ub19oZG1pX2VuY29kZXJfaGVscGVyX2Z1bmNzKTsKPj4+ICsgICAgZHJtX2VuY29kZXJfaW5p dChkcm0sIGVuY29kZXIsICZpbm5vX2hkbWlfZW5jb2Rlcl9mdW5jcywKPj4+ICsgICAgICAgICAg ICAgRFJNX01PREVfRU5DT0RFUl9UTURTLCBOVUxMKTsKPj4+ICsKPj4+ICsgICAgaGRtaS0+Y29u bmVjdG9yLnBvbGxlZCA9IERSTV9DT05ORUNUT1JfUE9MTF9IUEQ7Cj4+PiArCj4+PiArICAgIGRy bV9jb25uZWN0b3JfaGVscGVyX2FkZCgmaGRtaS0+Y29ubmVjdG9yLAo+Pj4gKyAgICAgICAgICAg ICAgICAgJmlubm9faGRtaV9jb25uZWN0b3JfaGVscGVyX2Z1bmNzKTsKPj4+ICsgICAgZHJtX2Nv bm5lY3Rvcl9pbml0KGRybSwgJmhkbWktPmNvbm5lY3RvciwgCj4+PiAmaW5ub19oZG1pX2Nvbm5l Y3Rvcl9mdW5jcywKPj4+ICsgICAgICAgICAgICAgICBEUk1fTU9ERV9DT05ORUNUT1JfSERNSUEp Owo+Pj4gKwo+Pj4gKyBkcm1fbW9kZV9jb25uZWN0b3JfYXR0YWNoX2VuY29kZXIoJmhkbWktPmNv bm5lY3RvciwgZW5jb2Rlcik7Cj4+PiArCj4+PiArICAgIHJldHVybiAwOwo+Pj4gK30KPj4+ICsK Pj4+ICtzdGF0aWMgaXJxcmV0dXJuX3QgaW5ub19oZG1pX2kyY19pcnEoc3RydWN0IGlubm9faGRt aSAqaGRtaSkKPj4+ICt7Cj4+PiArICAgIHN0cnVjdCBpbm5vX2hkbWlfaTJjICppMmMgPSBoZG1p LT5pMmM7Cj4+PiArICAgIHU4IHN0YXQ7Cj4+PiArCj4+PiArICAgIHN0YXQgPSBoZG1pX3JlYWRi KGhkbWksIEhETUlfSU5URVJSVVBUX1NUQVRVUzEpOwo+Pj4gKyAgICBpZiAoIShzdGF0ICYgbV9J TlRfRURJRF9SRUFEWSkpCj4+PiArICAgICAgICByZXR1cm4gSVJRX05PTkU7Cj4+PiArCj4+PiAr ICAgIC8qIENsZWFyIEhETUkgRURJRCBpbnRlcnJ1cHQgZmxhZyAqLwo+Pj4gKyAgICBoZG1pX3dy aXRlYihoZG1pLCBIRE1JX0lOVEVSUlVQVF9TVEFUVVMxLCBtX0lOVF9FRElEX1JFQURZKTsKPj4+ ICsKPj4+ICsgICAgY29tcGxldGUoJmkyYy0+Y21wKTsKPj4+ICsKPj4+ICsgICAgcmV0dXJuIElS UV9IQU5ETEVEOwo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMgaXJxcmV0dXJuX3QgaW5ub19oZG1p X2hhcmRpcnEoaW50IGlycSwgdm9pZCAqZGV2X2lkKQo+Pj4gK3sKPj4+ICsgICAgc3RydWN0IGlu bm9faGRtaSAqaGRtaSA9IGRldl9pZDsKPj4+ICsgICAgaXJxcmV0dXJuX3QgcmV0ID0gSVJRX05P TkU7Cj4+PiArICAgIHU4IGludGVycnVwdDsKPj4+ICsKPj4+ICsgICAgaWYgKGhkbWktPmkyYykK Pj4+ICsgICAgICAgIHJldCA9IGlubm9faGRtaV9pMmNfaXJxKGhkbWkpOwo+Pj4gKwo+Pj4gKyAg ICBpbnRlcnJ1cHQgPSBoZG1pX3JlYWRiKGhkbWksIEhETUlfU1RBVFVTKTsKPj4+ICsgICAgaWYg KGludGVycnVwdCAmIG1fSU5UX0hPVFBMVUcpIHsKPj4+ICsgICAgICAgIGhkbWlfbW9kYihoZG1p LCBIRE1JX1NUQVRVUywgbV9JTlRfSE9UUExVRywgbV9JTlRfSE9UUExVRyk7Cj4+PiArICAgICAg ICByZXQgPSBJUlFfV0FLRV9USFJFQUQ7Cj4+PiArICAgIH0KPj4+ICsKPj4+ICsgICAgcmV0dXJu IHJldDsKPj4+ICt9Cj4+PiArCj4+PiArc3RhdGljIGlycXJldHVybl90IGlubm9faGRtaV9pcnEo aW50IGlycSwgdm9pZCAqZGV2X2lkKQo+Pj4gK3sKPj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAq aGRtaSA9IGRldl9pZDsKPj4+ICsKPj4+ICsgICAgZHJtX2hlbHBlcl9ocGRfaXJxX2V2ZW50KGhk bWktPmNvbm5lY3Rvci5kZXYpOwo+Pj4gKwo+Pj4gKyAgICByZXR1cm4gSVJRX0hBTkRMRUQ7Cj4+ PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2kyY193YWl0KHN0cnVjdCBpbm5v X2hkbWkgKmhkbWkpCj4+PiArewo+Pj4gKyAgICBzdHJ1Y3QgaW5ub19oZG1pX2kyYyAqaTJjID0g aGRtaS0+aTJjOwo+Pj4gKyAgICBpbnQgc3RhdDsKPj4+ICsKPj4+ICsgICAgc3RhdCA9IHdhaXRf Zm9yX2NvbXBsZXRpb25fdGltZW91dCgmaTJjLT5jbXAsIEhaIC8gMTApOwo+Pj4gKyAgICBpZiAo IXN0YXQpIHsKPj4+ICsgICAgICAgIHN0YXQgPSB3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQo JmkyYy0+Y21wLCBIWiAvIDEwKTsKPj4+ICsgICAgICAgIGlmICghc3RhdCkKPj4+ICsgICAgICAg ICAgICByZXR1cm4gLUVBR0FJTjsKPj4+ICsgICAgfQo+Pj4gKwo+Pj4gKyAgICByZXR1cm4gMDsK Pj4+ICt9Cj4+PiArCj4+PiArc3RhdGljIGludCBpbm5vX2hkbWlfaTJjX3JlYWQoc3RydWN0IGlu bm9faGRtaSAqaGRtaSwgc3RydWN0IAo+Pj4gaTJjX21zZyAqbXNncykKPj4+ICt7Cj4+PiArICAg IGludCBsZW5ndGggPSBtc2dzLT5sZW47Cj4+PiArICAgIHU4ICpidWYgPSBtc2dzLT5idWY7Cj4+ PiArICAgIGludCByZXQ7Cj4+PiArCj4+PiArICAgIHJldCA9IGlubm9faGRtaV9pMmNfd2FpdCho ZG1pKTsKPj4+ICsgICAgaWYgKHJldCkKPj4+ICsgICAgICAgIHJldHVybiByZXQ7Cj4+PiArCj4+ PiArICAgIHdoaWxlIChsZW5ndGgtLSkKPj4+ICsgICAgICAgICpidWYrKyA9IGhkbWlfcmVhZGIo aGRtaSwgSERNSV9FRElEX0ZJRk9fQUREUik7Cj4+PiArCj4+PiArICAgIHJldHVybiAwOwo+Pj4g K30KPj4+ICsKPj4+ICtzdGF0aWMgaW50IGlubm9faGRtaV9pMmNfd3JpdGUoc3RydWN0IGlubm9f aGRtaSAqaGRtaSwgc3RydWN0IAo+Pj4gaTJjX21zZyAqbXNncykKPj4+ICt7Cj4+PiArICAgIHN0 cnVjdCBpbm5vX2hkbWlfaTJjICppMmMgPSBoZG1pLT5pMmM7Cj4+PiArCj4+PiArICAgIC8qCj4+ PiArICAgICAqIFRoZSBEREMgbW9kdWxlIG9ubHkgc3VwcG9ydCByZWFkIEVESUQgbWVzc2FnZSwg c28KPj4+ICsgICAgICogd2UgYXNzdW1lIHRoYXQgZWFjaCB3b3JkIHdyaXRlIHRvIHRoaXMgaTJj IGFkYXB0ZXIKPj4+ICsgICAgICogc2hvdWxkIGJlIHRoZSBvZmZzZXQgb2YgRURJRCB3b3JkIGFk ZHJlc3MuCj4+PiArICAgICAqLwo+Pj4gKyAgICBpZiAoKG1zZ3MtPmxlbiAhPSAxKSB8fAo+Pj4g KyAgICAgICAgKChtc2dzLT5hZGRyICE9IEREQ19BRERSKSAmJiAobXNncy0+YWRkciAhPSAKPj4+ IEREQ19TRUdNRU5UX0FERFIpKSkKPj4+ICsgICAgICAgIHJldHVybiAtRUlOVkFMOwo+Pj4gKwo+ Pj4gKyAgICByZWluaXRfY29tcGxldGlvbigmaTJjLT5jbXApOwo+Pj4gKwo+Pj4gKyAgICBpZiAo bXNncy0+YWRkciA9PSBERENfU0VHTUVOVF9BRERSKQo+Pj4gKyAgICAgICAgaGRtaS0+aTJjLT5z ZWdtZW50X2FkZHIgPSBtc2dzLT5idWZbMF07Cj4+PiArICAgIGlmIChtc2dzLT5hZGRyID09IERE Q19BRERSKQo+Pj4gKyAgICAgICAgaGRtaS0+aTJjLT5kZGNfYWRkciA9IG1zZ3MtPmJ1ZlswXTsK Pj4+ICsKPj4+ICsgICAgLyogU2V0IGVkaWQgZmlmbyBmaXJzdCBhZGRyICovCj4+PiArICAgIGhk bWlfd3JpdGViKGhkbWksIEhETUlfRURJRF9GSUZPX09GRlNFVCwgMHgwMCk7Cj4+PiArCj4+PiAr ICAgIC8qIFNldCBlZGlkIHdvcmQgYWRkcmVzcyAweDAwLzB4ODAgKi8KPj4+ICsgICAgaGRtaV93 cml0ZWIoaGRtaSwgSERNSV9FRElEX1dPUkRfQUREUiwgaGRtaS0+aTJjLT5kZGNfYWRkcik7Cj4+ PiArCj4+PiArICAgIC8qIFNldCBlZGlkIHNlZ21lbnQgcG9pbnRlciAqLwo+Pj4gKyAgICBoZG1p X3dyaXRlYihoZG1pLCBIRE1JX0VESURfU0VHTUVOVF9QT0lOVEVSLCAKPj4+IGhkbWktPmkyYy0+ c2VnbWVudF9hZGRyKTsKPj4+ICsKPj4+ICsgICAgcmV0dXJuIDA7Cj4+PiArfQo+Pj4gKwo+Pj4g K3N0YXRpYyBpbnQgaW5ub19oZG1pX2kyY194ZmVyKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCwK Pj4+ICsgICAgICAgICAgICAgICAgICBzdHJ1Y3QgaTJjX21zZyAqbXNncywgaW50IG51bSkKPj4+ ICt7Cj4+PiArICAgIHN0cnVjdCBpbm5vX2hkbWkgKmhkbWkgPSBpMmNfZ2V0X2FkYXBkYXRhKGFk YXApOwo+Pj4gKyAgICBzdHJ1Y3QgaW5ub19oZG1pX2kyYyAqaTJjID0gaGRtaS0+aTJjOwo+Pj4g KyAgICBpbnQgaSwgcmV0ID0gMDsKPj4+ICsKPj4+ICsgICAgbXV0ZXhfbG9jaygmaTJjLT5sb2Nr KTsKPj4+ICsKPj4+ICsgICAgLyogQ2xlYXIgdGhlIEVESUQgaW50ZXJydXB0IGZsYWcgYW5kIHVu bXV0ZSB0aGUgaW50ZXJydXB0ICovCj4+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfSU5U RVJSVVBUX01BU0sxLCBtX0lOVF9FRElEX1JFQURZKTsKPj4+ICsgICAgaGRtaV93cml0ZWIoaGRt aSwgSERNSV9JTlRFUlJVUFRfU1RBVFVTMSwgbV9JTlRfRURJRF9SRUFEWSk7Cj4+PiArCj4+PiAr ICAgIGZvciAoaSA9IDA7IGkgPCBudW07IGkrKykgewo+Pj4gKyAgICAgICAgZGV2X2RiZyhoZG1p LT5kZXYsICJ4ZmVyOiBudW06ICVkLyVkLCBsZW46ICVkLCBmbGFnczogJSN4XG4iLAo+Pj4gKyAg ICAgICAgICAgIGkgKyAxLCBudW0sIG1zZ3NbaV0ubGVuLCBtc2dzW2ldLmZsYWdzKTsKPj4+ICsK Pj4+ICsgICAgICAgIGlmIChtc2dzW2ldLmZsYWdzICYgSTJDX01fUkQpCj4+PiArICAgICAgICAg ICAgcmV0ID0gaW5ub19oZG1pX2kyY19yZWFkKGhkbWksICZtc2dzW2ldKTsKPj4+ICsgICAgICAg IGVsc2UKPj4+ICsgICAgICAgICAgICByZXQgPSBpbm5vX2hkbWlfaTJjX3dyaXRlKGhkbWksICZt c2dzW2ldKTsKPj4+ICsKPj4+ICsgICAgICAgIGlmIChyZXQgPCAwKQo+Pj4gKyAgICAgICAgICAg IGJyZWFrOwo+Pj4gKyAgICB9Cj4+PiArCj4+PiArICAgIGlmICghcmV0KQo+Pj4gKyAgICAgICAg cmV0ID0gbnVtOwo+Pj4gKwo+Pj4gKyAgICAvKiBNdXRlIEhETUkgRURJRCBpbnRlcnJ1cHQgKi8K Pj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9JTlRFUlJVUFRfTUFTSzEsIDApOwo+Pj4g Kwo+Pj4gKyAgICBtdXRleF91bmxvY2soJmkyYy0+bG9jayk7Cj4+PiArCj4+PiArICAgIHJldHVy biByZXQ7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyB1MzIgaW5ub19oZG1pX2kyY19mdW5jKHN0 cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlcikKPj4+ICt7Cj4+PiArICAgIHJldHVybiBJMkNfRlVO Q19JMkMgfCBJMkNfRlVOQ19TTUJVU19FTVVMOwo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMgY29u c3Qgc3RydWN0IGkyY19hbGdvcml0aG0gaW5ub19oZG1pX2FsZ29yaXRobSA9IHsKPj4+ICsgICAg Lm1hc3Rlcl94ZmVyICAgID0gaW5ub19oZG1pX2kyY194ZmVyLAo+Pj4gKyAgICAuZnVuY3Rpb25h bGl0eSAgICA9IGlubm9faGRtaV9pMmNfZnVuYywKPj4+ICt9Owo+Pj4gKwo+Pj4gK3N0YXRpYyBz dHJ1Y3QgaTJjX2FkYXB0ZXIgKmlubm9faGRtaV9pMmNfYWRhcHRlcihzdHJ1Y3QgaW5ub19oZG1p IAo+Pj4gKmhkbWkpCj4+PiArewo+Pj4gKyAgICBzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXA7Cj4+ PiArICAgIHN0cnVjdCBpbm5vX2hkbWlfaTJjICppMmM7Cj4+PiArICAgIGludCByZXQ7Cj4+PiAr Cj4+PiArICAgIGkyYyA9IGRldm1fa3phbGxvYyhoZG1pLT5kZXYsIHNpemVvZigqaTJjKSwgR0ZQ X0tFUk5FTCk7Cj4+PiArICAgIGlmICghaTJjKQo+Pj4gKyAgICAgICAgcmV0dXJuIEVSUl9QVFIo LUVOT01FTSk7Cj4+PiArCj4+PiArICAgIG11dGV4X2luaXQoJmkyYy0+bG9jayk7Cj4+PiArICAg IGluaXRfY29tcGxldGlvbigmaTJjLT5jbXApOwo+Pj4gKwo+Pj4gKyAgICBhZGFwID0gJmkyYy0+ YWRhcDsKPj4+ICsgICAgYWRhcC0+Y2xhc3MgPSBJMkNfQ0xBU1NfRERDOwo+Pj4gKyAgICBhZGFw LT5vd25lciA9IFRISVNfTU9EVUxFOwo+Pj4gKyAgICBhZGFwLT5kZXYucGFyZW50ID0gaGRtaS0+ ZGV2Owo+Pj4gKyAgICBhZGFwLT5kZXYub2Zfbm9kZSA9IGhkbWktPmRldi0+b2Zfbm9kZTsKPj4+ ICsgICAgYWRhcC0+YWxnbyA9ICZpbm5vX2hkbWlfYWxnb3JpdGhtOwo+Pj4gKyAgICBzdHJsY3B5 KGFkYXAtPm5hbWUsICJJbm5vIEhETUkiLCBzaXplb2YoYWRhcC0+bmFtZSkpOwo+Pj4gKyAgICBp MmNfc2V0X2FkYXBkYXRhKGFkYXAsIGhkbWkpOwo+Pj4gKwo+Pj4gKyAgICByZXQgPSBpMmNfYWRk X2FkYXB0ZXIoYWRhcCk7Cj4+PiArICAgIGlmIChyZXQpIHsKPj4+ICsgICAgICAgIGRldl93YXJu KGhkbWktPmRldiwgImNhbm5vdCBhZGQgJXMgSTJDIGFkYXB0ZXJcbiIsIAo+Pj4gYWRhcC0+bmFt ZSk7Cj4+PiArICAgICAgICBkZXZtX2tmcmVlKGhkbWktPmRldiwgaTJjKTsKPj4+ICsgICAgICAg IHJldHVybiBFUlJfUFRSKHJldCk7Cj4+PiArICAgIH0KPj4+ICsKPj4+ICsgICAgaGRtaS0+aTJj ID0gaTJjOwo+Pj4gKwo+Pj4gKyAgICBkZXZfaW5mbyhoZG1pLT5kZXYsICJyZWdpc3RlcmVkICVz IEkyQyBidXMgZHJpdmVyXG4iLCBhZGFwLT5uYW1lKTsKPj4+ICsKPj4+ICsgICAgcmV0dXJuIGFk YXA7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2JpbmQoc3RydWN0IGRl dmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlICptYXN0ZXIsCj4+PiArICAgICAgICAgICAgICAgICB2 b2lkICpkYXRhKQo+Pj4gK3sKPj4+ICsgICAgc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9 IHRvX3BsYXRmb3JtX2RldmljZShkZXYpOwo+Pj4gKyAgICBzdHJ1Y3QgZHJtX2RldmljZSAqZHJt ID0gZGF0YTsKPj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRtaTsKPj4+ICsgICAgc3RydWN0 IHJlc291cmNlICppb3JlczsKPj4+ICsgICAgaW50IGlycTsKPj4+ICsgICAgaW50IHJldDsKPj4+ ICsKPj4+ICsgICAgaGRtaSA9IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqaGRtaSksIEdGUF9L RVJORUwpOwo+Pj4gKyAgICBpZiAoIWhkbWkpCj4+PiArICAgICAgICByZXR1cm4gLUVOT01FTTsK Pj4+ICsKPj4+ICsgICAgaGRtaS0+ZGV2ID0gZGV2Owo+Pj4gKyAgICBoZG1pLT5kcm1fZGV2ID0g ZHJtOwo+Pj4gKwo+Pj4gKyAgICBpb3JlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJ T1JFU09VUkNFX01FTSwgMCk7Cj4+PiArICAgIGlmICghaW9yZXMpCj4+PiArICAgICAgICByZXR1 cm4gLUVOWElPOwo+Pj4gKwo+Pj4gKyAgICBoZG1pLT5yZWdzID0gZGV2bV9pb3JlbWFwX3Jlc291 cmNlKGRldiwgaW9yZXMpOwo+Pj4gKyAgICBpZiAoSVNfRVJSKGhkbWktPnJlZ3MpKQo+Pj4gKyAg ICAgICAgcmV0dXJuIFBUUl9FUlIoaGRtaS0+cmVncyk7Cj4+PiArCj4+PiArICAgIGhkbWktPnBj bGsgPSBkZXZtX2Nsa19nZXQoaGRtaS0+ZGV2LCAicGNsayIpOwo+Pj4gKyAgICBpZiAoSVNfRVJS KGhkbWktPnBjbGspKSB7Cj4+PiArICAgICAgICBkZXZfZXJyKGhkbWktPmRldiwgIlVuYWJsZSB0 byBnZXQgSERNSSBwY2xrIGNsa1xuIik7Cj4+PiArICAgICAgICByZXR1cm4gUFRSX0VSUihoZG1p LT5wY2xrKTsKPj4+ICsgICAgfQo+Pj4gKwo+Pj4gKyAgICByZXQgPSBjbGtfcHJlcGFyZV9lbmFi bGUoaGRtaS0+cGNsayk7Cj4+PiArICAgIGlmIChyZXQpIHsKPj4+ICsgICAgICAgIGRldl9lcnIo aGRtaS0+ZGV2LCAiQ2Fubm90IGVuYWJsZSBIRE1JIHBjbGsgY2xvY2s6ICVkXG4iLCAKPj4+IHJl dCk7Cj4+PiArICAgICAgICByZXR1cm4gcmV0Owo+Pj4gKyAgICB9Cj4+PiArCj4+PiArICAgIGly cSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7Cj4+PiArICAgIGlmIChpcnEgPCAwKQo+Pj4g KyAgICAgICAgcmV0dXJuIGlycTsKPj4+ICsKPj4+ICsgICAgaW5ub19oZG1pX3Jlc2V0KGhkbWkp Owo+Pj4gKwo+Pj4gKyAgICBoZG1pLT5kZGMgPSBpbm5vX2hkbWlfaTJjX2FkYXB0ZXIoaGRtaSk7 Cj4+PiArICAgIGlmIChJU19FUlIoaGRtaS0+ZGRjKSkgewo+Pj4gKyAgICAgICAgaGRtaS0+ZGRj ID0gTlVMTDsKPj4+ICsgICAgICAgIHJldHVybiBQVFJfRVJSKGhkbWktPmRkYyk7Cj4+PiArICAg IH0KPj4+ICsKPj4+ICsgICAgLyoKPj4+ICsgICAgICogV2hlbiBJUCBjb250cm9sbGVyIGhhdmVu J3QgY29uZmlndXJlZCB0byBhbiBhY2N1cmF0ZSB2aWRlbwo+Pj4gKyAgICAgKiB0aW1pbmcsIHRo ZW4gdGhlIFRNRFMgY2xvY2sgc291cmNlIHdvdWxkIGJlIHN3aXRjaGVkIHRvCj4+PiArICAgICAq IFBDTEtfSERNSSwgc28gd2UgbmVlZCB0byBpbml0IHRoZSBUTURTIHJhdGUgdG8gUENMSyByYXRl LAo+Pj4gKyAgICAgKiBhbmQgcmVjb25maWd1cmUgdGhlIEREQyBjbG9jay4KPj4+ICsgICAgICov Cj4+PiArICAgIGhkbWktPnRtZHNfcmF0ZSA9IGNsa19nZXRfcmF0ZShoZG1pLT5wY2xrKTsKPj4+ ICsgICAgaW5ub19oZG1pX2kyY19pbml0KGhkbWkpOwo+Pj4gKwo+Pj4gKyAgICByZXQgPSBpbm5v X2hkbWlfcmVnaXN0ZXIoZHJtLCBoZG1pKTsKPj4+ICsgICAgaWYgKHJldCkKPj4+ICsgICAgICAg IHJldHVybiByZXQ7Cj4+PiArCj4+PiArICAgIGRldl9zZXRfZHJ2ZGF0YShkZXYsIGhkbWkpOwo+ Pj4gKwo+Pj4gKyAgICAvKiBVbm11dGUgaG90cGx1ZyBpbnRlcnJ1cHQgKi8KPj4+ICsgICAgaGRt aV9tb2RiKGhkbWksIEhETUlfU1RBVFVTLCBtX01BU0tfSU5UX0hPVFBMVUcsIAo+Pj4gdl9NQVNL X0lOVF9IT1RQTFVHKDEpKTsKPj4+ICsKPj4+ICsgICAgcmV0ID0gZGV2bV9yZXF1ZXN0X3RocmVh ZGVkX2lycShkZXYsIGlycSwgaW5ub19oZG1pX2hhcmRpcnEsCj4+PiArICAgICAgICAgICAgICAg ICAgICBpbm5vX2hkbWlfaXJxLCBJUlFGX1NIQVJFRCwKPj4+ICsgICAgICAgICAgICAgICAgICAg IGRldl9uYW1lKGRldiksIGhkbWkpOwo+Pj4gKwo+Pj4gKyAgICByZXR1cm4gcmV0Owo+Pj4gK30K Pj4+ICsKPj4+ICtzdGF0aWMgdm9pZCBpbm5vX2hkbWlfdW5iaW5kKHN0cnVjdCBkZXZpY2UgKmRl diwgc3RydWN0IGRldmljZSAKPj4+ICptYXN0ZXIsCj4+PiArICAgICAgICAgICAgICAgICB2b2lk ICpkYXRhKQo+Pj4gK3sKPj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRtaSA9IGRldl9nZXRf ZHJ2ZGF0YShkZXYpOwo+Pj4gKwo+Pj4gKyBoZG1pLT5jb25uZWN0b3IuZnVuY3MtPmRlc3Ryb3ko JmhkbWktPmNvbm5lY3Rvcik7Cj4+PiArIGhkbWktPmVuY29kZXIuZnVuY3MtPmRlc3Ryb3koJmhk bWktPmVuY29kZXIpOwo+Pj4gKwo+Pj4gKyAgICBjbGtfZGlzYWJsZV91bnByZXBhcmUoaGRtaS0+ cGNsayk7Cj4+PiArICAgIGkyY19wdXRfYWRhcHRlcihoZG1pLT5kZGMpOwo+Pj4gK30KPj4+ICsK Pj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGNvbXBvbmVudF9vcHMgaW5ub19oZG1pX29wcyA9IHsK Pj4+ICsgICAgLmJpbmQgICAgPSBpbm5vX2hkbWlfYmluZCwKPj4+ICsgICAgLnVuYmluZCAgICA9 IGlubm9faGRtaV91bmJpbmQsCj4+PiArfTsKPj4+ICsKPj4+ICtzdGF0aWMgaW50IGlubm9faGRt aV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+Pj4gK3sKPj4+ICsgICAgcmV0 dXJuIGNvbXBvbmVudF9hZGQoJnBkZXYtPmRldiwgJmlubm9faGRtaV9vcHMpOwo+Pj4gK30KPj4+ ICsKPj4+ICtzdGF0aWMgaW50IGlubm9faGRtaV9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2Rldmlj ZSAqcGRldikKPj4+ICt7Cj4+PiArICAgIGNvbXBvbmVudF9kZWwoJnBkZXYtPmRldiwgJmlubm9f aGRtaV9vcHMpOwo+Pj4gKwo+Pj4gKyAgICByZXR1cm4gMDsKPj4+ICt9Cj4+PiArCj4+PiArc3Rh dGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgaW5ub19oZG1pX2R0X2lkc1tdID0gewo+Pj4g KyAgICB7IC5jb21wYXRpYmxlID0gInJvY2tjaGlwLHJrMzAzNi1pbm5vLWhkbWkiLAo+Pj4gKyAg ICB9LAo+Pj4gKyAgICB7fSwKPj4+ICt9Owo+Pj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIGlu bm9faGRtaV9kdF9pZHMpOwo+Pj4gKwo+Pj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVy IGlubm9faGRtaV9kcml2ZXIgPSB7Cj4+PiArICAgIC5wcm9iZSAgPSBpbm5vX2hkbWlfcHJvYmUs Cj4+PiArICAgIC5yZW1vdmUgPSBpbm5vX2hkbWlfcmVtb3ZlLAo+Pj4gKyAgICAuZHJpdmVyID0g ewo+Pj4gKyAgICAgICAgLm5hbWUgPSAiaW5ub2hkbWktcm9ja2NoaXAiLAo+Pj4gKyAgICAgICAg Lm9mX21hdGNoX3RhYmxlID0gaW5ub19oZG1pX2R0X2lkcywKPj4+ICsgICAgfSwKPj4+ICt9Owo+ Pj4gKwo+Pj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIoaW5ub19oZG1pX2RyaXZlcik7Cj4+PiAr Cj4+PiArTU9EVUxFX0FVVEhPUigiWmhlbmcgWWFuZyA8emhlbmd5YW5nQHJvY2stY2hpcHMuY29t PiIpOwo+Pj4gK01PRFVMRV9BVVRIT1IoIllha2lyIFlhbmcgPHlra0Byb2NrLWNoaXBzLmNvbT4i KTsKPj4+ICtNT0RVTEVfREVTQ1JJUFRJT04oIlJvY2tjaGlwIFNwZWNpZmljIElOTk8tSERNSSBE cml2ZXIiKTsKPj4+ICtNT0RVTEVfTElDRU5TRSgiR1BMIik7Cj4+PiArTU9EVUxFX0FMSUFTKCJw bGF0Zm9ybTppbm5vaGRtaS1yb2NrY2hpcCIpOwo+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1 L2RybS9yb2NrY2hpcC9pbm5vX2hkbWkuaCAKPj4+IGIvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlw L2lubm9faGRtaS5oCj4+PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+Pj4gaW5kZXggMDAwMDAwMC4u NGZmMTdhZAo+Pj4gLS0tIC9kZXYvbnVsbAo+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3JvY2tj aGlwL2lubm9faGRtaS5oCj4+PiBAQCAtMCwwICsxLDM2NCBAQAo+Pj4gKy8qCj4+PiArICogQ29w eXJpZ2h0IChDKSBGdXpob3UgUm9ja2NoaXAgRWxlY3Ryb25pY3MgQ28uTHRkCj4+PiArICogICAg WmhlbmcgWWFuZyA8emhlbmd5YW5nQHJvY2stY2hpcHMuY29tPgo+Pj4gKyAqICAgIFlha2lyIFlh bmcgPHlra0Byb2NrLWNoaXBzLmNvbT4KPj4+ICsgKgo+Pj4gKyAqIFRoaXMgc29mdHdhcmUgaXMg bGljZW5zZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKPj4+ICsg KiBMaWNlbnNlIHZlcnNpb24gMiwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZv dW5kYXRpb24sIAo+Pj4gYW5kCj4+PiArICogbWF5IGJlIGNvcGllZCwgZGlzdHJpYnV0ZWQsIGFu ZCBtb2RpZmllZCB1bmRlciB0aG9zZSB0ZXJtcy4KPj4+ICsgKgo+Pj4gKyAqIFRoaXMgcHJvZ3Jh bSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAo+Pj4g KyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdh cnJhbnR5IG9mCj4+PiArICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElD VUxBUiBQVVJQT1NFLiAgU2VlIHRoZQo+Pj4gKyAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNl IGZvciBtb3JlIGRldGFpbHMuCj4+PiArICovCj4+PiArCj4+PiArI2lmbmRlZiBfX0lOTk9fSERN SV9IX18KPj4+ICsjZGVmaW5lIF9fSU5OT19IRE1JX0hfXwo+Pj4gKwo+Pj4gKyNkZWZpbmUgRERD X1NFR01FTlRfQUREUiAgICAgICAgMHgzMAo+Pj4gKwo+Pj4gK2VudW0gUFdSX01PREUgewo+Pj4g KyAgICBOT1JNQUwsCj4+PiArICAgIExPV0VSX1BXUiwKPj4+ICt9Owo+Pj4gKwo+Pj4gKyNkZWZp bmUgSERNSV9TQ0xfUkFURSAgICAgICAgICAgICgxMDAqMTAwMCkKPj4+ICsjZGVmaW5lIEREQ19C VVNfRlJFUV9MICAgICAgICAgICAgMHg0Ygo+Pj4gKyNkZWZpbmUgRERDX0JVU19GUkVRX0ggICAg ICAgICAgICAweDRjCj4+PiArCj4+PiArI2RlZmluZSBIRE1JX1NZU19DVFJMICAgICAgICAgICAg MHgwMAo+Pj4gKyNkZWZpbmUgbV9SU1RfQU5BTE9HICAgICAgICAgICAgKDEgPDwgNikKPj4+ICsj ZGVmaW5lIHZfUlNUX0FOQUxPRyAgICAgICAgICAgICgwIDw8IDYpCj4+PiArI2RlZmluZSB2X05P VF9SU1RfQU5BTE9HICAgICAgICAoMSA8PCA2KQo+Pj4gKyNkZWZpbmUgbV9SU1RfRElHSVRBTCAg ICAgICAgICAgICgxIDw8IDUpCj4+PiArI2RlZmluZSB2X1JTVF9ESUdJVEFMICAgICAgICAgICAg KDAgPDwgNSkKPj4+ICsjZGVmaW5lIHZfTk9UX1JTVF9ESUdJVEFMICAgICAgICAoMSA8PCA1KQo+ Pj4gKyNkZWZpbmUgbV9SRUdfQ0xLX0lOViAgICAgICAgICAgICgxIDw8IDQpCj4+PiArI2RlZmlu ZSB2X1JFR19DTEtfTk9UX0lOViAgICAgICAgKDAgPDwgNCkKPj4+ICsjZGVmaW5lIHZfUkVHX0NM S19JTlYgICAgICAgICAgICAoMSA8PCA0KQo+Pj4gKyNkZWZpbmUgbV9WQ0xLX0lOViAgICAgICAg ICAgICgxIDw8IDMpCj4+PiArI2RlZmluZSB2X1ZDTEtfTk9UX0lOViAgICAgICAgICAgICgwIDw8 IDMpCj4+PiArI2RlZmluZSB2X1ZDTEtfSU5WICAgICAgICAgICAgKDEgPDwgMykKPj4+ICsjZGVm aW5lIG1fUkVHX0NMS19TT1VSQ0UgICAgICAgICgxIDw8IDIpCj4+PiArI2RlZmluZSB2X1JFR19D TEtfU09VUkNFX1RNRFMgICAgICAgICgwIDw8IDIpCj4+PiArI2RlZmluZSB2X1JFR19DTEtfU09V UkNFX1NZUyAgICAgICAgKDEgPDwgMikKPj4+ICsjZGVmaW5lIG1fUE9XRVIgICAgICAgICAgICAg ICAgKDEgPDwgMSkKPj4+ICsjZGVmaW5lIHZfUFdSX09OICAgICAgICAgICAgKDAgPDwgMSkKPj4+ ICsjZGVmaW5lIHZfUFdSX09GRiAgICAgICAgICAgICgxIDw8IDEpCj4+PiArI2RlZmluZSBtX0lO VF9QT0wgICAgICAgICAgICAoMSA8PCAwKQo+Pj4gKyNkZWZpbmUgdl9JTlRfUE9MX0hJR0ggICAg ICAgICAgICAxCj4+PiArI2RlZmluZSB2X0lOVF9QT0xfTE9XICAgICAgICAgICAgMAo+Pj4gKwo+ Pj4gKyNkZWZpbmUgSERNSV9WSURFT19DT05UUkwxICAgICAgICAweDAxCj4+PiArI2RlZmluZSBt X1ZJREVPX0lOUFVUX0ZPUk1BVCAgICAgICAgKDcgPDwgMSkKPj4+ICsjZGVmaW5lIG1fREVfU09V UkNFICAgICAgICAgICAgKDEgPDwgMCkKPj4+ICsjZGVmaW5lIHZfVklERU9fSU5QVVRfRk9STUFU KG4pICAgICAgICAobiA8PCAxKQo+Pj4gKyNkZWZpbmUgdl9ERV9FWFRFUk5BTCAgICAgICAgICAg IDEKPj4+ICsjZGVmaW5lIHZfREVfSU5URVJOQUwgICAgICAgICAgICAwCj4+PiArZW51bSB7Cj4+ PiArICAgIFZJREVPX0lOUFVUX1NEUl9SR0I0NDQgPSAwLAo+Pj4gKyAgICBWSURFT19JTlBVVF9E RFJfUkdCNDQ0ID0gNSwKPj4+ICsgICAgVklERU9fSU5QVVRfRERSX1lDQkNSNDIyID0gNgo+Pj4g K307Cj4+PiArCj4+PiArI2RlZmluZSBIRE1JX1ZJREVPX0NPTlRSTDIgICAgICAgIDB4MDIKPj4+ ICsjZGVmaW5lIG1fVklERU9fT1VUUFVUX0NPTE9SICAgICAgICAoMyA8PCA2KQo+Pj4gKyNkZWZp bmUgbV9WSURFT19JTlBVVF9CSVRTICAgICAgICAoMyA8PCA0KQo+Pj4gKyNkZWZpbmUgbV9WSURF T19JTlBVVF9DU1AgICAgICAgICgxIDw8IDApCj4+PiArI2RlZmluZSB2X1ZJREVPX09VVFBVVF9D T0xPUihuKSAgICAgICAgKCgobikgJiAweDMpIDw8IDYpCj4+PiArI2RlZmluZSB2X1ZJREVPX0lO UFVUX0JJVFMobikgICAgICAgIChuIDw8IDQpCj4+PiArI2RlZmluZSB2X1ZJREVPX0lOUFVUX0NT UChuKSAgICAgICAgKG4gPDwgMCkKPj4+ICtlbnVtIHsKPj4+ICsgICAgVklERU9fSU5QVVRfMTJC SVRTID0gMCwKPj4+ICsgICAgVklERU9fSU5QVVRfMTBCSVRTID0gMSwKPj4+ICsgICAgVklERU9f SU5QVVRfUkVWRVJUID0gMiwKPj4+ICsgICAgVklERU9fSU5QVVRfOEJJVFMgPSAzLAo+Pj4gK307 Cj4+PiArCj4+PiArI2RlZmluZSBIRE1JX1ZJREVPX0NPTlRSTCAgICAgICAgMHgwMwo+Pj4gKyNk ZWZpbmUgbV9WSURFT19BVVRPX0NTQyAgICAgICAgKDEgPDwgNykKPj4+ICsjZGVmaW5lIHZfVklE RU9fQVVUT19DU0MobikgICAgICAgIChuIDw8IDcpCj4+PiArI2RlZmluZSBtX1ZJREVPX0MwX0My X1NXQVAgICAgICAgICgxIDw8IDApCj4+PiArI2RlZmluZSB2X1ZJREVPX0MwX0MyX1NXQVAobikg ICAgICAgIChuIDw8IDApCj4+PiArZW51bSB7Cj4+PiArICAgIEMwX0MyX0NIQU5HRV9FTkFCTEUg PSAwLAo+Pj4gKyAgICBDMF9DMl9DSEFOR0VfRElTQUJMRSA9IDEsCj4+PiArICAgIEFVVE9fQ1ND X0RJU0FCTEUgPSAwLAo+Pj4gKyAgICBBVVRPX0NTQ19FTkFCTEUgPSAxLAo+Pj4gK307Cj4+PiAr Cj4+PiArI2RlZmluZSBIRE1JX1ZJREVPX0NPTlRSTDMgICAgICAgIDB4MDQKPj4+ICsjZGVmaW5l IG1fQ09MT1JfREVQVEhfTk9UX0lORElDQVRFRCAgICAoMSA8PCA0KQo+Pj4gKyNkZWZpbmUgbV9T T0YgICAgICAgICAgICAgICAgKDEgPDwgMykKPj4+ICsjZGVmaW5lIG1fQ09MT1JfUkFOR0UgICAg ICAgICAgICAoMSA8PCAyKQo+Pj4gKyNkZWZpbmUgbV9DU0MgICAgICAgICAgICAgICAgKDEgPDwg MCkKPj4+ICsjZGVmaW5lIHZfQ09MT1JfREVQVEhfTk9UX0lORElDQVRFRChuKSAgICAoKG4pIDw8 IDQpCj4+PiArI2RlZmluZSB2X1NPRl9FTkFCTEUgICAgICAgICAgICAoMCA8PCAzKQo+Pj4gKyNk ZWZpbmUgdl9TT0ZfRElTQUJMRSAgICAgICAgICAgICgxIDw8IDMpCj4+PiArI2RlZmluZSB2X0NP TE9SX1JBTkdFX0ZVTEwgICAgICAgICgxIDw8IDIpCj4+PiArI2RlZmluZSB2X0NPTE9SX1JBTkdF X0xJTUlURUQgICAgICAgICgwIDw8IDIpCj4+PiArI2RlZmluZSB2X0NTQ19FTkFCTEUgICAgICAg ICAgICAxCj4+PiArI2RlZmluZSB2X0NTQ19ESVNBQkxFICAgICAgICAgICAgMAo+Pj4gKwo+Pj4g KyNkZWZpbmUgSERNSV9BVl9NVVRFICAgICAgICAgICAgMHgwNQo+Pj4gKyNkZWZpbmUgbV9BVk1V VEVfQ0xFQVIgICAgICAgICAgICAoMSA8PCA3KQo+Pj4gKyNkZWZpbmUgbV9BVk1VVEVfRU5BQkxF ICAgICAgICAgICAgKDEgPDwgNikKPj4+ICsjZGVmaW5lIG1fQVVESU9fTVVURSAgICAgICAgICAg ICgxIDw8IDEpCj4+PiArI2RlZmluZSBtX1ZJREVPX0JMQUNLICAgICAgICAgICAgKDEgPDwgMCkK Pj4+ICsjZGVmaW5lIHZfQVZNVVRFX0NMRUFSKG4pICAgICAgICAobiA8PCA3KQo+Pj4gKyNkZWZp bmUgdl9BVk1VVEVfRU5BQkxFKG4pICAgICAgICAobiA8PCA2KQo+Pj4gKyNkZWZpbmUgdl9BVURJ T19NVVRFKG4pICAgICAgICAgICAgKG4gPDwgMSkKPj4+ICsjZGVmaW5lIHZfVklERU9fTVVURShu KSAgICAgICAgICAgIChuIDw8IDApCj4+PiArCj4+PiArI2RlZmluZSBIRE1JX1ZJREVPX1RJTUlO R19DVEwgICAgICAgIDB4MDgKPj4+ICsjZGVmaW5lIHZfSFNZTkNfUE9MQVJJVFkobikgICAgICAg IChuIDw8IDMpCj4+PiArI2RlZmluZSB2X1ZTWU5DX1BPTEFSSVRZKG4pICAgICAgICAobiA8PCAy KQo+Pj4gKyNkZWZpbmUgdl9JTkVUTEFDRShuKSAgICAgICAgICAgIChuIDw8IDEpCj4+PiArI2Rl ZmluZSB2X0VYVEVSQU5MX1ZJREVPKG4pICAgICAgICAobiA8PCAwKQo+Pj4gKwo+Pj4gKyNkZWZp bmUgSERNSV9WSURFT19FWFRfSFRPVEFMX0wgICAgICAgIDB4MDkKPj4+ICsjZGVmaW5lIEhETUlf VklERU9fRVhUX0hUT1RBTF9IICAgICAgICAweDBhCj4+PiArI2RlZmluZSBIRE1JX1ZJREVPX0VY VF9IQkxBTktfTCAgICAgICAgMHgwYgo+Pj4gKyNkZWZpbmUgSERNSV9WSURFT19FWFRfSEJMQU5L X0ggICAgICAgIDB4MGMKPj4+ICsjZGVmaW5lIEhETUlfVklERU9fRVhUX0hERUxBWV9MICAgICAg ICAweDBkCj4+PiArI2RlZmluZSBIRE1JX1ZJREVPX0VYVF9IREVMQVlfSCAgICAgICAgMHgwZQo+ Pj4gKyNkZWZpbmUgSERNSV9WSURFT19FWFRfSERVUkFUSU9OX0wgICAgMHgwZgo+Pj4gKyNkZWZp bmUgSERNSV9WSURFT19FWFRfSERVUkFUSU9OX0ggICAgMHgxMAo+Pj4gKyNkZWZpbmUgSERNSV9W SURFT19FWFRfVlRPVEFMX0wgICAgICAgIDB4MTEKPj4+ICsjZGVmaW5lIEhETUlfVklERU9fRVhU X1ZUT1RBTF9IICAgICAgICAweDEyCj4+PiArI2RlZmluZSBIRE1JX1ZJREVPX0VYVF9WQkxBTksg ICAgICAgIDB4MTMKPj4+ICsjZGVmaW5lIEhETUlfVklERU9fRVhUX1ZERUxBWSAgICAgICAgMHgx NAo+Pj4gKyNkZWZpbmUgSERNSV9WSURFT19FWFRfVkRVUkFUSU9OICAgIDB4MTUKPj4+ICsKPj4+ ICsjZGVmaW5lIEhETUlfVklERU9fQ1NDX0NPRUYgICAgICAgIDB4MTgKPj4+ICsKPj4+ICsjZGVm aW5lIEhETUlfQVVESU9fQ1RSTDEgICAgICAgIDB4MzUKPj4+ICtlbnVtIHsKPj4+ICsgICAgQ1RT X1NPVVJDRV9JTlRFUk5BTCA9IDAsCj4+PiArICAgIENUU19TT1VSQ0VfRVhURVJOQUwgPSAxLAo+ Pj4gK307Cj4+PiArI2RlZmluZSB2X0NUU19TT1VSQ0UobikgICAgICAgICAgICAobiA8PCA3KQo+ Pj4gKwo+Pj4gK2VudW0gewo+Pj4gKyAgICBET1dOU0FNUExFX0RJU0FCTEUgPSAwLAo+Pj4gKyAg ICBET1dOU0FNUExFXzFfMiA9IDEsCj4+PiArICAgIERPV05TQU1QTEVfMV80ID0gMiwKPj4+ICt9 Owo+Pj4gKyNkZWZpbmUgdl9ET1dOX1NBTVBMRShuKSAgICAgICAgKG4gPDwgNSkKPj4+ICsKPj4+ ICtlbnVtIHsKPj4+ICsgICAgQVVESU9fU09VUkNFX0lJUyA9IDAsCj4+PiArICAgIEFVRElPX1NP VVJDRV9TUERJRiA9IDEsCj4+PiArfTsKPj4+ICsjZGVmaW5lIHZfQVVESU9fU09VUkNFKG4pICAg ICAgICAobiA8PCAzKQo+Pj4gKwo+Pj4gKyNkZWZpbmUgdl9NQ0xLX0VOQUJMRShuKSAgICAgICAg KG4gPDwgMikKPj4+ICtlbnVtIHsKPj4+ICsgICAgTUNMS18xMjhGUyA9IDAsCj4+PiArICAgIE1D TEtfMjU2RlMgPSAxLAo+Pj4gKyAgICBNQ0xLXzM4NEZTID0gMiwKPj4+ICsgICAgTUNMS181MTJG UyA9IDMsCj4+PiArfTsKPj4+ICsjZGVmaW5lIHZfTUNMS19SQVRJTyhuKSAgICAgICAgICAgIChu KQo+Pj4gKwo+Pj4gKyNkZWZpbmUgQVVESU9fU0FNUExFX1JBVEUgICAgICAgIDB4MzcKPj4+ICtl bnVtIHsKPj4+ICsgICAgQVVESU9fMzJLID0gMHgzLAo+Pj4gKyAgICBBVURJT180NDFLID0gMHgw LAo+Pj4gKyAgICBBVURJT180OEsgPSAweDIsCj4+PiArICAgIEFVRElPXzg4MksgPSAweDgsCj4+ PiArICAgIEFVRElPXzk2SyA9IDB4YSwKPj4+ICsgICAgQVVESU9fMTc2NEsgPSAweGMsCj4+PiAr ICAgIEFVRElPXzE5MksgPSAweGUsCj4+PiArfTsKPj4+ICsKPj4+ICsjZGVmaW5lIEFVRElPX0ky U19NT0RFICAgICAgICAgICAgMHgzOAo+Pj4gK2VudW0gewo+Pj4gKyAgICBJMlNfQ0hBTk5FTF8x XzIgPSAxLAo+Pj4gKyAgICBJMlNfQ0hBTk5FTF8zXzQgPSAzLAo+Pj4gKyAgICBJMlNfQ0hBTk5F TF81XzYgPSA3LAo+Pj4gKyAgICBJMlNfQ0hBTk5FTF83XzggPSAweGYKPj4+ICt9Owo+Pj4gKyNk ZWZpbmUgdl9JMlNfQ0hBTk5FTChuKSAgICAgICAgKChuKSA8PCAyKQo+Pj4gK2VudW0gewo+Pj4g KyAgICBJMlNfU1RBTkRBUkQgPSAwLAo+Pj4gKyAgICBJMlNfTEVGVF9KVVNUSUZJRUQgPSAxLAo+ Pj4gKyAgICBJMlNfUklHSFRfSlVTVElGSUVEID0gMiwKPj4+ICt9Owo+Pj4gKyNkZWZpbmUgdl9J MlNfTU9ERShuKSAgICAgICAgICAgIChuKQo+Pj4gKwo+Pj4gKyNkZWZpbmUgQVVESU9fSTJTX01B UCAgICAgICAgICAgIDB4MzkKPj4+ICsjZGVmaW5lIEFVRElPX0kyU19TV0FQU19TUERJRiAgICAg ICAgMHgzYQo+Pj4gKyNkZWZpbmUgdl9TUElERl9GUkVRKG4pICAgICAgICAgICAgKG4pCj4+PiAr Cj4+PiArI2RlZmluZSBOXzMySyAgICAgICAgICAgICAgICAweDEwMDAKPj4+ICsjZGVmaW5lIE5f NDQxSyAgICAgICAgICAgICAgICAweDE4ODAKPj4+ICsjZGVmaW5lIE5fODgySyAgICAgICAgICAg ICAgICAweDMxMDAKPj4+ICsjZGVmaW5lIE5fMTc2NEsgICAgICAgICAgICAgICAgMHg2MjAwCj4+ PiArI2RlZmluZSBOXzQ4SyAgICAgICAgICAgICAgICAweDE4MDAKPj4+ICsjZGVmaW5lIE5fOTZL ICAgICAgICAgICAgICAgIDB4MzAwMAo+Pj4gKyNkZWZpbmUgTl8xOTJLICAgICAgICAgICAgICAg IDB4NjAwMAo+Pj4gKwo+Pj4gKyNkZWZpbmUgSERNSV9BVURJT19DSEFOTkVMX1NUQVRVUyAgICAw eDNlCj4+PiArI2RlZmluZSBtX0FVRElPX1NUQVRVU19OTFBDTSAgICAgICAgKDEgPDwgNykKPj4+ ICsjZGVmaW5lIG1fQVVESU9fU1RBVFVTX1VTRSAgICAgICAgKDEgPDwgNikKPj4+ICsjZGVmaW5l IG1fQVVESU9fU1RBVFVTX0NPUFlSSUdIVCAgICAoMSA8PCA1KQo+Pj4gKyNkZWZpbmUgbV9BVURJ T19TVEFUVVNfQURESVRJT04gICAgICAgICgzIDw8IDIpCj4+PiArI2RlZmluZSBtX0FVRElPX1NU QVRVU19DTEtfQUNDVVJBQ1kgICAgKDIgPDwgMCkKPj4+ICsjZGVmaW5lIHZfQVVESU9fU1RBVFVT X05MUENNKG4pICAgICAgICAoKG4gJiAxKSA8PCA3KQo+Pj4gKyNkZWZpbmUgQVVESU9fTl9IICAg ICAgICAgICAgMHgzZgo+Pj4gKyNkZWZpbmUgQVVESU9fTl9NICAgICAgICAgICAgMHg0MAo+Pj4g KyNkZWZpbmUgQVVESU9fTl9MICAgICAgICAgICAgMHg0MQo+Pj4gKwo+Pj4gKyNkZWZpbmUgSERN SV9BVURJT19DVFNfSCAgICAgICAgMHg0NQo+Pj4gKyNkZWZpbmUgSERNSV9BVURJT19DVFNfTSAg ICAgICAgMHg0Ngo+Pj4gKyNkZWZpbmUgSERNSV9BVURJT19DVFNfTCAgICAgICAgMHg0Nwo+Pj4g Kwo+Pj4gKyNkZWZpbmUgSERNSV9ERENfQ0xLX0wgICAgICAgICAgICAweDRiCj4+PiArI2RlZmlu ZSBIRE1JX0REQ19DTEtfSCAgICAgICAgICAgIDB4NGMKPj4+ICsKPj4+ICsjZGVmaW5lIEhETUlf RURJRF9TRUdNRU5UX1BPSU5URVIgICAgMHg0ZAo+Pj4gKyNkZWZpbmUgSERNSV9FRElEX1dPUkRf QUREUiAgICAgICAgMHg0ZQo+Pj4gKyNkZWZpbmUgSERNSV9FRElEX0ZJRk9fT0ZGU0VUICAgICAg ICAweDRmCj4+PiArI2RlZmluZSBIRE1JX0VESURfRklGT19BRERSICAgICAgICAweDUwCj4+PiAr Cj4+PiArI2RlZmluZSBIRE1JX1BBQ0tFVF9TRU5EX01BTlVBTCAgICAgICAgMHg5Ywo+Pj4gKyNk ZWZpbmUgSERNSV9QQUNLRVRfU0VORF9BVVRPICAgICAgICAweDlkCj4+PiArI2RlZmluZSBtX1BB Q0tFVF9HQ1BfRU4gICAgICAgICAgICAoMSA8PCA3KQo+Pj4gKyNkZWZpbmUgbV9QQUNLRVRfTVNJ X0VOICAgICAgICAgICAgKDEgPDwgNikKPj4+ICsjZGVmaW5lIG1fUEFDS0VUX1NESV9FTiAgICAg ICAgICAgICgxIDw8IDUpCj4+PiArI2RlZmluZSBtX1BBQ0tFVF9WU0lfRU4gICAgICAgICAgICAo MSA8PCA0KQo+Pj4gKyNkZWZpbmUgdl9QQUNLRVRfR0NQX0VOKG4pICAgICAgICAoKG4gJiAxKSA8 PCA3KQo+Pj4gKyNkZWZpbmUgdl9QQUNLRVRfTVNJX0VOKG4pICAgICAgICAoKG4gJiAxKSA8PCA2 KQo+Pj4gKyNkZWZpbmUgdl9QQUNLRVRfU0RJX0VOKG4pICAgICAgICAoKG4gJiAxKSA8PCA1KQo+ Pj4gKyNkZWZpbmUgdl9QQUNLRVRfVlNJX0VOKG4pICAgICAgICAoKG4gJiAxKSA8PCA0KQo+Pj4g Kwo+Pj4gKyNkZWZpbmUgSERNSV9DT05UUk9MX1BBQ0tFVF9CVUZfSU5ERVggICAgMHg5Zgo+Pj4g K2VudW0gewo+Pj4gKyAgICBJTkZPRlJBTUVfVlNJID0gMHgwNSwKPj4+ICsgICAgSU5GT0ZSQU1F X0FWSSA9IDB4MDYsCj4+PiArICAgIElORk9GUkFNRV9BQUkgPSAweDA4LAo+Pj4gK307Cj4+PiAr Cj4+PiArI2RlZmluZSBIRE1JX0NPTlRST0xfUEFDS0VUX0FERFIgICAgMHhhMAo+Pj4gKyNkZWZp bmUgSERNSV9TSVpFX1ZTSV9JTkZPRlJBTUUgICAgICAgIDB4MEEKPj4+ICsjZGVmaW5lIEhETUlf U0laRV9BVklfSU5GT0ZSQU1FICAgICAgICAweDExCj4+PiArI2RlZmluZSBIRE1JX1NJWkVfQVVE SU9fSU5GT0ZSQU1FICAgIDB4MEYKPj4+ICtlbnVtIHsKPj4+ICsgICAgQVZJX0NPTE9SX01PREVf UkdCID0gMCwKPj4+ICsgICAgQVZJX0NPTE9SX01PREVfWUNCQ1I0MjIgPSAxLAo+Pj4gKyAgICBB VklfQ09MT1JfTU9ERV9ZQ0JDUjQ0NCA9IDIsCj4+PiArICAgIEFWSV9DT0xPUklNRVRSWV9OT19E QVRBID0gMCwKPj4+ICsKPj4+ICsgICAgQVZJX0NPTE9SSU1FVFJZX1NNUFRFXzE3ME0gPSAxLAo+ Pj4gKyAgICBBVklfQ09MT1JJTUVUUllfSVRVNzA5ID0gMiwKPj4+ICsgICAgQVZJX0NPTE9SSU1F VFJZX0VYVEVOREVEID0gMywKPj4+ICsKPj4+ICsgICAgQVZJX0NPREVEX0ZSQU1FX0FTUEVDVF9O T19EQVRBID0gMCwKPj4+ICsgICAgQVZJX0NPREVEX0ZSQU1FX0FTUEVDVF80XzMgPSAxLAo+Pj4g KyAgICBBVklfQ09ERURfRlJBTUVfQVNQRUNUXzE2XzkgPSAyLAo+Pj4gKwo+Pj4gKyAgICBBQ1RJ VkVfQVNQRUNUX1JBVEVfU0FNRV9BU19DT0RFRF9GUkFNRSA9IDB4MDgsCj4+PiArICAgIEFDVElW RV9BU1BFQ1RfUkFURV80XzMgPSAweDA5LAo+Pj4gKyAgICBBQ1RJVkVfQVNQRUNUX1JBVEVfMTZf OSA9IDB4MEEsCj4+PiArICAgIEFDVElWRV9BU1BFQ1RfUkFURV8xNF85ID0gMHgwQiwKPj4+ICt9 Owo+Pj4gKwo+Pj4gKyNkZWZpbmUgSERNSV9IRENQX0NUUkwgICAgICAgICAgICAweDUyCj4+PiAr I2RlZmluZSBtX0hETUlfRFZJICAgICAgICAgICAgKDEgPDwgMSkKPj4+ICsjZGVmaW5lIHZfSERN SV9EVkkobikgICAgICAgICAgICAobiA8PCAxKQo+Pj4gKwo+Pj4gKyNkZWZpbmUgSERNSV9JTlRF UlJVUFRfTUFTSzEgICAgICAgIDB4YzAKPj4+ICsjZGVmaW5lIEhETUlfSU5URVJSVVBUX1NUQVRV UzEgICAgICAgIDB4YzEKPj4+ICsjZGVmaW5lICAgIG1fSU5UX0FDVElWRV9WU1lOQyAgICAgICAg KDEgPDwgNSkKPj4+ICsjZGVmaW5lIG1fSU5UX0VESURfUkVBRFkgICAgICAgICgxIDw8IDIpCj4+ PiArCj4+PiArI2RlZmluZSBIRE1JX0lOVEVSUlVQVF9NQVNLMiAgICAgICAgMHhjMgo+Pj4gKyNk ZWZpbmUgSERNSV9JTlRFUlJVUFRfU1RBVFVTMiAgICAgICAgMHhjMwo+Pj4gKyNkZWZpbmUgbV9J TlRfSERDUF9FUlIgICAgICAgICAgICAoMSA8PCA3KQo+Pj4gKyNkZWZpbmUgbV9JTlRfQktTVl9G TEFHICAgICAgICAgICAgKDEgPDwgNikKPj4+ICsjZGVmaW5lIG1fSU5UX0hEQ1BfT0sgICAgICAg ICAgICAoMSA8PCA0KQo+Pj4gKwo+Pj4gKyNkZWZpbmUgSERNSV9TVEFUVVMgICAgICAgICAgICAw eGM4Cj4+PiArI2RlZmluZSBtX0hPVFBMVUcgICAgICAgICAgICAoMSA8PCA3KQo+Pj4gKyNkZWZp bmUgbV9NQVNLX0lOVF9IT1RQTFVHICAgICAgICAoMSA8PCA1KQo+Pj4gKyNkZWZpbmUgbV9JTlRf SE9UUExVRyAgICAgICAgICAgICgxIDw8IDEpCj4+PiArI2RlZmluZSB2X01BU0tfSU5UX0hPVFBM VUcobikgICAgICAgICgobiAmIDB4MSkgPDwgNSkKPj4+ICsKPj4+ICsjZGVmaW5lIEhETUlfQ09M T1JCQVIgICAgICAgICAgICAgICAgICAgMHhjOQo+Pj4gKwo+Pj4gKyNkZWZpbmUgSERNSV9QSFlf U1lOQyAgICAgICAgICAgIDB4Y2UKPj4+ICsjZGVmaW5lIEhETUlfUEhZX1NZU19DVEwgICAgICAg IDB4ZTAKPj4+ICsjZGVmaW5lIG1fVE1EU19DTEtfU09VUkNFICAgICAgICAoMSA8PCA1KQo+Pj4g KyNkZWZpbmUgdl9UTURTX0ZST01fUExMICAgICAgICAgICAgKDAgPDwgNSkKPj4+ICsjZGVmaW5l IHZfVE1EU19GUk9NX0dFTiAgICAgICAgICAgICgxIDw8IDUpCj4+PiArI2RlZmluZSBtX1BIQVNF X0NMSyAgICAgICAgICAgICgxIDw8IDQpCj4+PiArI2RlZmluZSB2X0RFRkFVTFRfUEhBU0UgICAg ICAgICAgICAoMCA8PCA0KQo+Pj4gKyNkZWZpbmUgdl9TWU5DX1BIQVNFICAgICAgICAgICAgKDEg PDwgNCkKPj4+ICsjZGVmaW5lIG1fVE1EU19DVVJSRU5UX1BXUiAgICAgICAgKDEgPDwgMykKPj4+ ICsjZGVmaW5lIHZfVFVSTl9PTl9DVVJSRU5UICAgICAgICAoMCA8PCAzKQo+Pj4gKyNkZWZpbmUg dl9DQVRfT0ZGX0NVUlJFTlQgICAgICAgICgxIDw8IDMpCj4+PiArI2RlZmluZSBtX0JBTkRHQVBf UFdSICAgICAgICAgICAgKDEgPDwgMikKPj4+ICsjZGVmaW5lIHZfQkFOREdBUF9QV1JfVVAgICAg ICAgICgwIDw8IDIpCj4+PiArI2RlZmluZSB2X0JBTkRHQVBfUFdSX0RPV04gICAgICAgICgxIDw8 IDIpCj4+PiArI2RlZmluZSBtX1BMTF9QV1IgICAgICAgICAgICAoMSA8PCAxKQo+Pj4gKyNkZWZp bmUgdl9QTExfUFdSX1VQICAgICAgICAgICAgKDAgPDwgMSkKPj4+ICsjZGVmaW5lIHZfUExMX1BX Ul9ET1dOICAgICAgICAgICAgKDEgPDwgMSkKPj4+ICsjZGVmaW5lIG1fVE1EU19DSEdfUFdSICAg ICAgICAgICAgKDEgPDwgMCkKPj4+ICsjZGVmaW5lIHZfVE1EU19DSEdfUFdSX1VQICAgICAgICAo MCA8PCAwKQo+Pj4gKyNkZWZpbmUgdl9UTURTX0NIR19QV1JfRE9XTiAgICAgICAgKDEgPDwgMCkK Pj4+ICsKPj4+ICsjZGVmaW5lIEhETUlfUEhZX0NIR19QV1IgICAgICAgIDB4ZTEKPj4+ICsjZGVm aW5lIHZfQ0xLX0NIR19QV1IobikgICAgICAgICgobiAmIDEpIDw8IDMpCj4+PiArI2RlZmluZSB2 X0RBVEFfQ0hHX1BXUihuKSAgICAgICAgKChuICYgNykgPDwgMCkKPj4+ICsKPj4+ICsjZGVmaW5l IEhETUlfUEhZX0RSSVZFUiAgICAgICAgICAgIDB4ZTIKPj4+ICsjZGVmaW5lIHZfQ0xLX01BSU5f RFJJVkVSKG4pICAgICAgICAobiA8PCA0KQo+Pj4gKyNkZWZpbmUgdl9EQVRBX01BSU5fRFJJVkVS KG4pICAgICAgICAobiA8PCAwKQo+Pj4gKwo+Pj4gKyNkZWZpbmUgSERNSV9QSFlfUFJFX0VNUEhB U0lTICAgICAgICAweGUzCj4+PiArI2RlZmluZSB2X1BSRV9FTVBIQVNJUyhuKSAgICAgICAgKChu ICYgNykgPDwgNCkKPj4+ICsjZGVmaW5lIHZfQ0xLX1BSRV9EUklWRVIobikgICAgICAgICgobiAm IDMpIDw8IDIpCj4+PiArI2RlZmluZSB2X0RBVEFfUFJFX0RSSVZFUihuKSAgICAgICAgKChuICYg MykgPDwgMCkKPj4+ICsKPj4+ICsjZGVmaW5lIEhETUlfUEhZX0ZFRURCQUNLX0RJVl9SQVRJT19M T1cgICAgICAgIDB4ZTcKPj4+ICsjZGVmaW5lIHZfRkVFREJBQ0tfRElWX0xPVyhuKSAgICAgICAg ICAgIChuICYgMHhmZikKPj4+ICsjZGVmaW5lIEhETUlfUEhZX0ZFRURCQUNLX0RJVl9SQVRJT19I SUdIICAgIDB4ZTgKPj4+ICsjZGVmaW5lIHZfRkVFREJBQ0tfRElWX0hJR0gobikgICAgICAgICAg ICAobiAmIDEpCj4+PiArCj4+PiArI2RlZmluZSBIRE1JX1BIWV9QUkVfRElWX1JBVElPICAgICAg ICAweGVkCj4+PiArI2RlZmluZSB2X1BSRV9ESVZfUkFUSU8obikgICAgICAgIChuICYgMHgxZikK Pj4+ICsKPj4+ICsjZGVmaW5lIEhETUlfQ0VDX0NUUkwgICAgICAgICAgICAweGQwCj4+PiArI2Rl ZmluZSBtX0FESlVTVF9GT1JfSElTRU5TRSAgICAgICAgKDEgPDwgNikKPj4+ICsjZGVmaW5lIG1f UkVKRUNUX1JYX0JST0FEQ0FTVCAgICAgICAgKDEgPDwgNSkKPj4+ICsjZGVmaW5lIG1fQlVTRlJF RVRJTUVfRU5BQkxFICAgICAgICAoMSA8PCAyKQo+Pj4gKyNkZWZpbmUgbV9SRUpFQ1RfUlggICAg ICAgICAgICAoMSA8PCAxKQo+Pj4gKyNkZWZpbmUgbV9TVEFSVF9UWCAgICAgICAgICAgICgxIDw8 IDApCj4+PiArCj4+PiArI2RlZmluZSBIRE1JX0NFQ19EQVRBICAgICAgICAgICAgMHhkMQo+Pj4g KyNkZWZpbmUgSERNSV9DRUNfVFhfT0ZGU0VUICAgICAgICAweGQyCj4+PiArI2RlZmluZSBIRE1J X0NFQ19SWF9PRkZTRVQgICAgICAgIDB4ZDMKPj4+ICsjZGVmaW5lIEhETUlfQ0VDX0NMS19IICAg ICAgICAgICAgMHhkNAo+Pj4gKyNkZWZpbmUgSERNSV9DRUNfQ0xLX0wgICAgICAgICAgICAweGQ1 Cj4+PiArI2RlZmluZSBIRE1JX0NFQ19UWF9MRU5HVEggICAgICAgIDB4ZDYKPj4+ICsjZGVmaW5l IEhETUlfQ0VDX1JYX0xFTkdUSCAgICAgICAgMHhkNwo+Pj4gKyNkZWZpbmUgSERNSV9DRUNfVFhf SU5UX01BU0sgICAgICAgIDB4ZDgKPj4+ICsjZGVmaW5lIG1fVFhfRE9ORSAgICAgICAgICAgICgx IDw8IDMpCj4+PiArI2RlZmluZSBtX1RYX05PQUNLICAgICAgICAgICAgKDEgPDwgMikKPj4+ICsj ZGVmaW5lIG1fVFhfQlJPQURDQVNUX1JFSiAgICAgICAgKDEgPDwgMSkKPj4+ICsjZGVmaW5lIG1f VFhfQlVTTk9URlJFRSAgICAgICAgICAgICgxIDw8IDApCj4+PiArCj4+PiArI2RlZmluZSBIRE1J X0NFQ19SWF9JTlRfTUFTSyAgICAgICAgMHhkOQo+Pj4gKyNkZWZpbmUgbV9SWF9MQV9FUlIgICAg ICAgICAgICAoMSA8PCA0KQo+Pj4gKyNkZWZpbmUgbV9SWF9HTElUQ0ggICAgICAgICAgICAoMSA8 PCAzKQo+Pj4gKyNkZWZpbmUgbV9SWF9ET05FICAgICAgICAgICAgKDEgPDwgMCkKPj4+ICsKPj4+ ICsjZGVmaW5lIEhETUlfQ0VDX1RYX0lOVCAgICAgICAgICAgIDB4ZGEKPj4+ICsjZGVmaW5lIEhE TUlfQ0VDX1JYX0lOVCAgICAgICAgICAgIDB4ZGIKPj4+ICsjZGVmaW5lIEhETUlfQ0VDX0JVU0ZS RUVUSU1FX0wgICAgICAgIDB4ZGMKPj4+ICsjZGVmaW5lIEhETUlfQ0VDX0JVU0ZSRUVUSU1FX0gg ICAgICAgIDB4ZGQKPj4+ICsjZGVmaW5lIEhETUlfQ0VDX0xPR0lDQUREUiAgICAgICAgMHhkZQo+ Pj4gKwo+Pj4gKyNlbmRpZiAvKiBfX0lOTk9fSERNSV9IX18gKi8KPj4KPj4KPgo+CgoKX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxp bmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHA6Ly9saXN0cy5mcmVl ZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK From mboxrd@z Thu Jan 1 00:00:00 1970 From: ykk@rock-chips.com (Yakir Yang) Date: Mon, 25 Jan 2016 09:22:31 +0800 Subject: [PATCH v3 1/2] drm: rockchip/hdmi: add Innosilicon HDMI support In-Reply-To: <56A47E6F.8050104@gmail.com> References: <1452850598-30859-1-git-send-email-ykk@rock-chips.com> <1452850690-31760-1-git-send-email-ykk@rock-chips.com> <569C3E36.10103@rock-chips.com> <56A47E6F.8050104@gmail.com> Message-ID: <56A578D7.5070101@rock-chips.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Caesar, On 01/24/2016 03:34 PM, Caesar Wang wrote: > Hi > > ? 2016?01?18? 09:21, Mark yao ??: >> Hi Yakir >> >> I'd like you can change your patch title into "drm/rockchip/hdmi", so >> when I search patches use "drm/rockchip" can find your patch. >> >> and I have some advices mail inline. >> >> Thanks:-) >> >> On 2016?01?15? 17:38, Yakir Yang wrote: >>> The Innosilicon HDMI is a low power HDMI 1.4 transmitter >>> IP, and it have been integrated on some rockchip CPUs >>> (like RK3036, RK312x). >>> >>> Signed-off-by: Yakir Yang >>> --- >>> Changes in v3: >>> - Use encoder enable/disable function, and remove the encoder DPMS >>> function >>> - Keep HDMI PLL power on in standby mode >>> >>> Changes in v2: >>> - Using DRM atomic helper functions for connector init (Mark) >>> - Remove "hdmi->connector.encoder = encoder;" (Mark) >>> >>> drivers/gpu/drm/rockchip/Kconfig | 8 + >>> drivers/gpu/drm/rockchip/Makefile | 1 + >>> drivers/gpu/drm/rockchip/inno_hdmi.c | 999 >>> +++++++++++++++++++++++++++++++++++ >>> drivers/gpu/drm/rockchip/inno_hdmi.h | 364 +++++++++++++ >>> 4 files changed, 1372 insertions(+) >>> create mode 100644 drivers/gpu/drm/rockchip/inno_hdmi.c >>> create mode 100644 drivers/gpu/drm/rockchip/inno_hdmi.h >>> >>> diff --git a/drivers/gpu/drm/rockchip/Kconfig >>> b/drivers/gpu/drm/rockchip/Kconfig >>> index 35215f6..a5014e0 100644 >>> --- a/drivers/gpu/drm/rockchip/Kconfig >>> +++ b/drivers/gpu/drm/rockchip/Kconfig >>> @@ -25,3 +25,11 @@ config ROCKCHIP_DW_HDMI >>> for the Synopsys DesignWare HDMI driver. If you want to >>> enable HDMI on RK3288 based SoC, you should selet this >>> option. >>> + >>> +config ROCKCHIP_INNO_HDMI >>> + tristate "Rockchip specific extensions for Innosilicon HDMI" >>> + depends on DRM_ROCKCHIP >>> + help >>> + This selects support for Rockchip SoC specific extensions >>> + for the Innosilicon HDMI driver. If you want to enable >>> + HDMI on RK3036 based SoC, you should selet this option. > > That's seem has some conflicts since the MIPI driver land in mainline. > So you need update it based on the lastest kernel. > Yep, thanks for your reminder, need to update the patch. And by the way the latest version of this patch have been updated to v5 :) https://patchwork.kernel.org/patch/8058061/ >>> diff --git a/drivers/gpu/drm/rockchip/Makefile >>> b/drivers/gpu/drm/rockchip/Makefile >>> index a9d380f..da2bf76 100644 >>> --- a/drivers/gpu/drm/rockchip/Makefile >>> +++ b/drivers/gpu/drm/rockchip/Makefile >>> @@ -6,6 +6,7 @@ rockchipdrm-y := rockchip_drm_drv.o >>> rockchip_drm_fb.o rockchip_drm_fbdev.o \ >>> rockchip_drm_gem.o >>> obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o >>> +obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o >>> obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o \ >>> rockchip_vop_reg.o >>> diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c >>> b/drivers/gpu/drm/rockchip/inno_hdmi.c >>> new file mode 100644 >>> index 0000000..dc98179 >>> --- /dev/null >>> +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c >>> @@ -0,0 +1,999 @@ >>> +/* >>> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd >>> + * Zheng Yang >>> + * Yakir Yang >>> + * >>> + * This software is licensed under the terms of the GNU General Public >>> + * License version 2, as published by the Free Software Foundation, >>> and >>> + * may be copied, distributed, and modified under those terms. >>> + * >>> + * This program is distributed in the hope that it will be useful, >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >>> + * GNU General Public License for more details. >>> + */ >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include "rockchip_drm_drv.h" >>> +#include "rockchip_drm_vop.h" >>> + >>> +#include "inno_hdmi.h" >>> + >>> +#define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x) >>> + >>> +struct hdmi_data_info { >>> + int vic; >>> + bool sink_is_hdmi; >>> + bool sink_has_audio; >>> + unsigned int enc_in_format; >>> + unsigned int enc_out_format; >>> + unsigned int colorimetry; >>> +}; >>> + >>> +struct inno_hdmi_i2c { >>> + struct i2c_adapter adap; >>> + >>> + u8 ddc_addr; >>> + u8 segment_addr; >>> + >>> + struct mutex lock; >>> + struct completion cmp; >>> +}; >>> + >>> +struct inno_hdmi { >>> + struct device *dev; >>> + struct drm_device *drm_dev; >>> + >>> + int irq; >>> + struct clk *pclk; >>> + void __iomem *regs; >>> + >>> + struct drm_connector connector; >>> + struct drm_encoder encoder; >>> + >>> + struct inno_hdmi_i2c *i2c; >>> + struct i2c_adapter *ddc; >>> + >>> + unsigned int tmds_rate; >>> + >>> + struct hdmi_data_info hdmi_data; >>> + struct drm_display_mode previous_mode; >>> +}; >>> + >>> +enum { >>> + CSC_ITU601_16_235_TO_RGB_0_255_8BIT, >>> + CSC_ITU601_0_255_TO_RGB_0_255_8BIT, >>> + CSC_ITU709_16_235_TO_RGB_0_255_8BIT, >>> + CSC_RGB_0_255_TO_ITU601_16_235_8BIT, >>> + CSC_RGB_0_255_TO_ITU709_16_235_8BIT, >>> + CSC_RGB_0_255_TO_RGB_16_235_8BIT, >>> +}; >>> + >>> +static const char coeff_csc[][24] = { >>> + /* >>> + * YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]): >>> + * R = 1.164*Y + 1.596*V - 204 >>> + * G = 1.164*Y - 0.391*U - 0.813*V + 154 >>> + * B = 1.164*Y + 2.018*U - 258 >>> + */ >>> + { >>> + 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc, >>> + 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a, >>> + 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02 >>> + }, >>> + /* >>> + * YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]): >>> + * R = Y + 1.402*V - 248 >>> + * G = Y - 0.344*U - 0.714*V + 135 >>> + * B = Y + 1.772*U - 227 >>> + */ >>> + { >>> + 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8, >>> + 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87, >>> + 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3 >>> + }, >>> + /* >>> + * YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]): >>> + * R = 1.164*Y + 1.793*V - 248 >>> + * G = 1.164*Y - 0.213*U - 0.534*V + 77 >>> + * B = 1.164*Y + 2.115*U - 289 >>> + */ >>> + { >>> + 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8, >>> + 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d, >>> + 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21 >>> + }, >>> + >>> + /* >>> + * RGB2YUV:601 SD mode: >>> + * Cb = -0.291G - 0.148R + 0.439B + 128 >>> + * Y = 0.504G + 0.257R + 0.098B + 16 >>> + * Cr = -0.368G + 0.439R - 0.071B + 128 >>> + */ >>> + { >>> + 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80, >>> + 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e, >>> + 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80 >>> + }, >>> + /* >>> + * RGB2YUV:709 HD mode: >>> + * Cb = - 0.338G - 0.101R + 0.439B + 128 >>> + * Y = 0.614G + 0.183R + 0.062B + 16 >>> + * Cr = - 0.399G + 0.439R - 0.040B + 128 >>> + */ >>> + { >>> + 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80, >>> + 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10, >>> + 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80 >>> + }, >>> + /* >>> + * RGB[0:255]2RGB[16:235]: >>> + * R' = R x (235-16)/255 + 16; >>> + * G' = G x (235-16)/255 + 16; >>> + * B' = B x (235-16)/255 + 16; >>> + */ >>> + { >>> + 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10, >>> + 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, >>> + 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10 >>> + }, >>> +}; >>> + >>> +static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset) >>> +{ >>> + return readl_relaxed(hdmi->regs + (offset) * 0x04); >>> +} >>> + >>> +static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, >>> u32 val) >>> +{ >>> + writel_relaxed(val, hdmi->regs + (offset) * 0x04); >>> +} >>> + >>> +static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset, >>> + u32 msk, u32 val) >>> +{ >>> + u8 temp = hdmi_readb(hdmi, offset) & ~msk; >>> + >>> + temp |= val & msk; >>> + hdmi_writeb(hdmi, offset, temp); >>> +} >>> + >>> +static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi) >>> +{ >>> + int ddc_bus_freq; >>> + >>> + ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE; >>> + >>> + hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); >>> + hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); >>> + >>> + /* Clear the EDID interrupt flag and mute the interrupt */ >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); >>> +} >>> + >>> +static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable) >>> +{ >>> + if (enable) >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON); >>> + else >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF); >>> +} >>> + >>> +static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode) >>> +{ >>> + switch (mode) { >>> + case NORMAL: >>> + inno_hdmi_sys_power(hdmi, false); >>> + >>> + hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f); >>> + hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb); >>> + >>> + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10); >>> + hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01); >>> + >>> + inno_hdmi_sys_power(hdmi, true); >>> + break; >>> + >>> + case LOWER_PWR: >>> + inno_hdmi_sys_power(hdmi, false); >>> + hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00); >>> + hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00); >>> + hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); >>> + >>> + break; >>> + >>> + default: >>> + dev_err(hdmi->dev, "Unknown power mode %d\n", mode); >>> + } >>> +} >>> + >>> +static void inno_hdmi_reset(struct inno_hdmi *hdmi) >>> +{ >>> + u32 val; >>> + u32 msk; >>> + >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL); >>> + udelay(100); >>> + >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG); >>> + udelay(100); >>> + >>> + msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL; >>> + val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | >>> v_INT_POL_HIGH; >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val); >>> + >>> + inno_hdmi_set_pwr_mode(hdmi, NORMAL); >>> +} >>> + >>> +static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi) >>> +{ >>> + char info[HDMI_SIZE_AVI_INFOFRAME] = {0}; >>> + int avi_color_mode; >>> + int i; >>> + >>> + hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); >>> + >>> + info[0] = 0x82; >>> + info[1] = 0x02; >>> + info[2] = 0x0D; >>> + info[3] = info[0] + info[1] + info[2]; >>> + >>> + if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_RGB) >>> + avi_color_mode = AVI_COLOR_MODE_RGB; >>> + else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444) >>> + avi_color_mode = AVI_COLOR_MODE_YCBCR444; >>> + else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422) >>> + avi_color_mode = AVI_COLOR_MODE_YCBCR422; >>> + else >>> + avi_color_mode = AVI_COLOR_MODE_RGB; >>> + >>> + info[4] = (avi_color_mode << 5); >>> + info[5] = (AVI_COLORIMETRY_NO_DATA << 6) | >>> + (AVI_CODED_FRAME_ASPECT_NO_DATA << 4) | >>> + ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME; >>> + >>> + info[6] = 0; >>> + info[7] = hdmi->hdmi_data.vic; >>> + >>> + if (hdmi->hdmi_data.vic == 6 || hdmi->hdmi_data.vic == 7 || >>> + hdmi->hdmi_data.vic == 21 || hdmi->hdmi_data.vic == 22) >>> + info[8] = 1; >>> + else >>> + info[8] = 0; >>> + >>> + /* Calculate avi info frame checKsum */ >>> + for (i = 4; i < HDMI_SIZE_AVI_INFOFRAME; i++) >>> + info[3] += info[i]; >>> + info[3] = 0x100 - info[3]; >>> + >>> + for (i = 0; i < HDMI_SIZE_AVI_INFOFRAME; i++) >>> + hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, info[i]); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi) >>> +{ >>> + char info[HDMI_SIZE_VSI_INFOFRAME] = {0}; >>> + int i; >>> + >>> + hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, m_PACKET_VSI_EN, >>> + v_PACKET_VSI_EN(0)); >>> + >>> + hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_VSI); >>> + >>> + /* Header Bytes */ >>> + info[0] = 0x81; >>> + info[1] = 0x01; >>> + >>> + /* PB1 - PB3 contain the 24bit IEEE Registration Identifier */ >>> + info[4] = 0x03; >>> + info[5] = 0x0c; >>> + info[6] = 0x00; >>> + >>> + /* PB4 - HDMI_Video_Format into bits 7:5 */ >>> + info[7] = 0; >>> + >>> + /* >>> + * PB5 - Depending on the video format, this byte will contain >>> + * either the HDMI_VIC code in buts 7:0, OR the 3D_Structure in >>> + * bits 7:4. >>> + */ >>> + info[2] = 0x06 - 2; >>> + info[8] = 0; >>> + info[9] = 0; >>> + >>> + info[3] = info[0] + info[1] + info[2]; >>> + >>> + /* Calculate info frame checKsum */ >>> + for (i = 4; i < HDMI_SIZE_VSI_INFOFRAME; i++) >>> + info[3] += info[i]; >>> + info[3] = 0x100 - info[3]; >>> + >>> + for (i = 0; i < HDMI_SIZE_VSI_INFOFRAME; i++) >>> + hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, info[i]); >>> + >>> + hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, m_PACKET_VSI_EN, >>> + v_PACKET_VSI_EN(1)); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) >>> +{ >>> + struct hdmi_data_info *data = &hdmi->hdmi_data; >>> + int c0_c2_change = 0; >>> + int csc_enable = 0; >>> + int csc_mode = 0; >>> + int auto_csc = 0; >>> + int value; >>> + int i; >>> + >>> + /* Input video mode is SDR RGB24bit, data enable signal from >>> external */ >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL | >>> + v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444)); >>> + >>> + /* Input color hardcode to RGB, and output color hardcode to >>> RGB888 */ >>> + value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | >>> + v_VIDEO_OUTPUT_COLOR(0) | >>> + v_VIDEO_INPUT_CSP(0); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value); >>> + >>> + if (data->enc_out_format == data->enc_out_format) { >>> + if ((data->enc_in_format == HDMI_COLORSPACE_RGB) || >>> + (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) { >>> + value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); >>> + >>> + hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, >>> + m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP, >>> + v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) | >>> + v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE)); >>> + return 0; >>> + } >>> + } >>> + >>> + if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) { >>> + if ((data->enc_in_format == HDMI_COLORSPACE_RGB) && >>> + (data->enc_out_format == HDMI_COLORSPACE_YUV444)) { >>> + csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT; >>> + auto_csc = AUTO_CSC_DISABLE; >>> + c0_c2_change = C0_C2_CHANGE_DISABLE; >>> + csc_enable = v_CSC_ENABLE; >>> + } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) && >>> + (data->enc_out_format == HDMI_COLORSPACE_RGB)) { >>> + csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; >>> + auto_csc = AUTO_CSC_ENABLE; >>> + c0_c2_change = C0_C2_CHANGE_DISABLE; >>> + csc_enable = v_CSC_DISABLE; >>> + } >>> + } else { >>> + if ((data->enc_in_format == HDMI_COLORSPACE_RGB) && >>> + (data->enc_out_format == HDMI_COLORSPACE_YUV444)) { >>> + csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT; >>> + auto_csc = AUTO_CSC_DISABLE; >>> + c0_c2_change = C0_C2_CHANGE_DISABLE; >>> + csc_enable = v_CSC_ENABLE; >>> + } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) && >>> + (data->enc_out_format == HDMI_COLORSPACE_RGB)) { >>> + csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT; >>> + auto_csc = AUTO_CSC_ENABLE; >>> + c0_c2_change = C0_C2_CHANGE_DISABLE; >>> + csc_enable = v_CSC_DISABLE; >>> + } >>> + } >>> + >>> + for (i = 0; i < 24; i++) >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i, >>> + coeff_csc[csc_mode][i]); >>> + >>> + value = v_SOF_DISABLE | csc_enable | >>> v_COLOR_DEPTH_NOT_INDICATED(1); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); >>> + hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC | >>> + m_VIDEO_C0_C2_SWAP, v_VIDEO_AUTO_CSC(auto_csc) | >>> + v_VIDEO_C0_C2_SWAP(c0_c2_change)); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, >>> + struct drm_display_mode *mode) >>> +{ >>> + int value; >>> + >>> + /* Set detail external video timing polarity and interlace mode */ >>> + value = v_EXTERANL_VIDEO(1); >>> + value |= mode->flags & DRM_MODE_FLAG_PHSYNC ? >>> + v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0); >>> + value |= mode->flags & DRM_MODE_FLAG_PVSYNC ? >>> + v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0); >>> + value |= mode->flags & DRM_MODE_FLAG_INTERLACE ? >>> + v_INETLACE(1) : v_INETLACE(0); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value); >>> + >>> + /* Set detail external video timing */ >>> + value = mode->htotal; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); >>> + >>> + value = mode->htotal - mode->hdisplay; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); >>> + >>> + value = mode->hsync_start - mode->hdisplay; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); >>> + >>> + value = mode->hsync_end - mode->hsync_start; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & >>> 0xFF); >>> + >>> + value = mode->vtotal; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); >>> + >>> + value = mode->vtotal - mode->vdisplay; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF); >>> + >>> + value = mode->vsync_start - mode->vdisplay; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF); >>> + >>> + value = mode->vsync_end - mode->vsync_start; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF); >>> + >>> + hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e); >>> + hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c); >>> + hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_setup(struct inno_hdmi *hdmi, >>> + struct drm_display_mode *mode) >>> +{ >>> + int value; > > Where be used? > I guess you should remove it. > > > > - > Caesar >>> + >>> + hdmi->hdmi_data.vic = drm_match_cea_mode(mode); >>> + >>> + hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB; >>> + hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB; >>> + >>> + if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) || >>> + (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) || >>> + (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) || >>> + (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18)) >>> + hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; >>> + else >>> + hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; >>> + >>> + /* Mute video and audio output */ >>> + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, >>> + v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); >>> + >>> + /* Set HDMI Mode */ >>> + hdmi_writeb(hdmi, HDMI_HDCP_CTRL, >>> + v_HDMI_DVI(hdmi->hdmi_data.sink_is_hdmi)); >>> + >>> + inno_hdmi_config_video_timing(hdmi, mode); >>> + >>> + inno_hdmi_config_video_csc(hdmi); >>> + >>> + if (hdmi->hdmi_data.sink_is_hdmi) { >>> + inno_hdmi_config_video_avi(hdmi); >>> + inno_hdmi_config_video_vsi(hdmi); >>> + } >>> + >>> + /* >>> + * When IP controller have configured to an accurate video >>> + * timing, then the TMDS clock source would be switched to >>> + * DCLK_LCDC, so we need to init the TMDS rate to mode pixel >>> + * clock rate, and reconfigure the DDC clock. >>> + */ >>> + hdmi->tmds_rate = mode->clock * 1000; >>> + inno_hdmi_i2c_init(hdmi); >>> + >>> + /* Unmute video and audio output */ >>> + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, >>> + v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); >>> + >>> + return 0; >>> +} >>> + >>> +static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder, >>> + struct drm_display_mode *mode, >>> + struct drm_display_mode *adj_mode) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(encoder); >>> + >>> + inno_hdmi_setup(hdmi, adj_mode); >>> + >>> + /* Store the display mode for plugin/DKMS poweron events */ >> >> I think DKMS should be DPMS. >> >>> + memcpy(&hdmi->previous_mode, adj_mode, >>> sizeof(hdmi->previous_mode)); >>> +} >>> + >>> +static void inno_hdmi_encoder_enable(struct drm_encoder *encoder) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(encoder); >>> + >>> + inno_hdmi_set_pwr_mode(hdmi, NORMAL); >>> +} >>> + >>> +static void inno_hdmi_encoder_disable(struct drm_encoder *encoder) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(encoder); >>> + >>> + inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR); >>> +} >>> + >>> +static void inno_hdmi_encoder_commit(struct drm_encoder *encoder) >>> +{ >>> +} >>> + >>> +static void inno_hdmi_encoder_prepare(struct drm_encoder *encoder) >>> +{ >>> + rockchip_drm_crtc_mode_config(encoder->crtc, >>> DRM_MODE_CONNECTOR_HDMIA, >>> + ROCKCHIP_OUT_MODE_P888); >> >> Can you move mode_config into inno_hdmi_encoder_enable, and remove >> .prepare and .commit? >> >>> +} >>> + >>> +static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder, >>> + const struct drm_display_mode *mode, >>> + struct drm_display_mode *adj_mode) >>> +{ >>> + return true; >>> +} >>> + >>> +static struct drm_encoder_helper_funcs >>> inno_hdmi_encoder_helper_funcs = { >>> + .enable = inno_hdmi_encoder_enable, >>> + .disable = inno_hdmi_encoder_disable, >>> + .mode_fixup = inno_hdmi_encoder_mode_fixup, >>> + .mode_set = inno_hdmi_encoder_mode_set, >>> + .prepare = inno_hdmi_encoder_prepare, >>> + .commit = inno_hdmi_encoder_commit, >> >> On drm atomic, I think if support .enable and .disable callbacks, >> then .prepare and .commit is not needed. >> >>> +}; >>> + >>> +static struct drm_encoder_funcs inno_hdmi_encoder_funcs = { >>> + .destroy = drm_encoder_cleanup, >>> +}; >>> + >>> +static enum drm_connector_status >>> +inno_hdmi_connector_detect(struct drm_connector *connector, bool >>> force) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(connector); >>> + >>> + return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ? >>> + connector_status_connected : connector_status_disconnected; >>> +} >>> + >>> +static int inno_hdmi_connector_get_modes(struct drm_connector >>> *connector) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(connector); >>> + struct edid *edid; >>> + int ret = 0; >>> + >>> + if (!hdmi->ddc) >>> + return 0; >>> + >>> + edid = drm_get_edid(connector, hdmi->ddc); >>> + if (edid) { >>> + hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid); >>> + hdmi->hdmi_data.sink_has_audio = >>> drm_detect_monitor_audio(edid); >>> + drm_mode_connector_update_edid_property(connector, edid); >>> + ret = drm_add_edid_modes(connector, edid); >>> + kfree(edid); >>> + } >>> + >>> + return ret; >>> +} >>> + >>> +static enum drm_mode_status >>> +inno_hdmi_connector_mode_valid(struct drm_connector *connector, >>> + struct drm_display_mode *mode) >>> +{ >>> + return MODE_OK; >>> +} >>> + >>> +static struct drm_encoder * >>> +inno_hdmi_connector_best_encoder(struct drm_connector *connector) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(connector); >>> + >>> + return &hdmi->encoder; >>> +} >>> + >>> +static int >>> +inno_hdmi_probe_single_connector_modes(struct drm_connector >>> *connector, >>> + uint32_t maxX, uint32_t maxY) >>> +{ >>> + return drm_helper_probe_single_connector_modes(connector, 1920, >>> 1080); >>> +} >>> + >>> +static void inno_hdmi_connector_destroy(struct drm_connector >>> *connector) >>> +{ >>> + drm_connector_unregister(connector); >>> + drm_connector_cleanup(connector); >>> +} >>> + >>> +static struct drm_connector_funcs inno_hdmi_connector_funcs = { >>> + .dpms = drm_atomic_helper_connector_dpms, >>> + .fill_modes = inno_hdmi_probe_single_connector_modes, >>> + .detect = inno_hdmi_connector_detect, >>> + .destroy = inno_hdmi_connector_destroy, >>> + .reset = drm_atomic_helper_connector_reset, >>> + .atomic_duplicate_state = >>> drm_atomic_helper_connector_duplicate_state, >>> + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, >>> +}; >>> + >>> +static struct drm_connector_helper_funcs >>> inno_hdmi_connector_helper_funcs = { >>> + .get_modes = inno_hdmi_connector_get_modes, >>> + .mode_valid = inno_hdmi_connector_mode_valid, >>> + .best_encoder = inno_hdmi_connector_best_encoder, >>> +}; >>> + >>> +static int inno_hdmi_register(struct drm_device *drm, struct >>> inno_hdmi *hdmi) >>> +{ >>> + struct drm_encoder *encoder = &hdmi->encoder; >>> + >>> + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, >>> hdmi->dev->of_node); >> >> Keep 80 characters :-) . >> >>> + /* >>> + * If we failed to find the CRTC(s) which this encoder is >>> + * supposed to be connected to, it's because the CRTC has >>> + * not been registered yet. Defer probing, and hope that >>> + * the required CRTC is added later. >>> + */ >>> + if (encoder->possible_crtcs == 0) >>> + return -EPROBE_DEFER; >>> + >>> + drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs); >>> + drm_encoder_init(drm, encoder, &inno_hdmi_encoder_funcs, >>> + DRM_MODE_ENCODER_TMDS, NULL); >>> + >>> + hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; >>> + >>> + drm_connector_helper_add(&hdmi->connector, >>> + &inno_hdmi_connector_helper_funcs); >>> + drm_connector_init(drm, &hdmi->connector, >>> &inno_hdmi_connector_funcs, >>> + DRM_MODE_CONNECTOR_HDMIA); >>> + >>> + drm_mode_connector_attach_encoder(&hdmi->connector, encoder); >>> + >>> + return 0; >>> +} >>> + >>> +static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi) >>> +{ >>> + struct inno_hdmi_i2c *i2c = hdmi->i2c; >>> + u8 stat; >>> + >>> + stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1); >>> + if (!(stat & m_INT_EDID_READY)) >>> + return IRQ_NONE; >>> + >>> + /* Clear HDMI EDID interrupt flag */ >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); >>> + >>> + complete(&i2c->cmp); >>> + >>> + return IRQ_HANDLED; >>> +} >>> + >>> +static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id) >>> +{ >>> + struct inno_hdmi *hdmi = dev_id; >>> + irqreturn_t ret = IRQ_NONE; >>> + u8 interrupt; >>> + >>> + if (hdmi->i2c) >>> + ret = inno_hdmi_i2c_irq(hdmi); >>> + >>> + interrupt = hdmi_readb(hdmi, HDMI_STATUS); >>> + if (interrupt & m_INT_HOTPLUG) { >>> + hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG); >>> + ret = IRQ_WAKE_THREAD; >>> + } >>> + >>> + return ret; >>> +} >>> + >>> +static irqreturn_t inno_hdmi_irq(int irq, void *dev_id) >>> +{ >>> + struct inno_hdmi *hdmi = dev_id; >>> + >>> + drm_helper_hpd_irq_event(hdmi->connector.dev); >>> + >>> + return IRQ_HANDLED; >>> +} >>> + >>> +static int inno_hdmi_i2c_wait(struct inno_hdmi *hdmi) >>> +{ >>> + struct inno_hdmi_i2c *i2c = hdmi->i2c; >>> + int stat; >>> + >>> + stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); >>> + if (!stat) { >>> + stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); >>> + if (!stat) >>> + return -EAGAIN; >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct >>> i2c_msg *msgs) >>> +{ >>> + int length = msgs->len; >>> + u8 *buf = msgs->buf; >>> + int ret; >>> + >>> + ret = inno_hdmi_i2c_wait(hdmi); >>> + if (ret) >>> + return ret; >>> + >>> + while (length--) >>> + *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct >>> i2c_msg *msgs) >>> +{ >>> + struct inno_hdmi_i2c *i2c = hdmi->i2c; >>> + >>> + /* >>> + * The DDC module only support read EDID message, so >>> + * we assume that each word write to this i2c adapter >>> + * should be the offset of EDID word address. >>> + */ >>> + if ((msgs->len != 1) || >>> + ((msgs->addr != DDC_ADDR) && (msgs->addr != >>> DDC_SEGMENT_ADDR))) >>> + return -EINVAL; >>> + >>> + reinit_completion(&i2c->cmp); >>> + >>> + if (msgs->addr == DDC_SEGMENT_ADDR) >>> + hdmi->i2c->segment_addr = msgs->buf[0]; >>> + if (msgs->addr == DDC_ADDR) >>> + hdmi->i2c->ddc_addr = msgs->buf[0]; >>> + >>> + /* Set edid fifo first addr */ >>> + hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00); >>> + >>> + /* Set edid word address 0x00/0x80 */ >>> + hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr); >>> + >>> + /* Set edid segment pointer */ >>> + hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, >>> hdmi->i2c->segment_addr); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap, >>> + struct i2c_msg *msgs, int num) >>> +{ >>> + struct inno_hdmi *hdmi = i2c_get_adapdata(adap); >>> + struct inno_hdmi_i2c *i2c = hdmi->i2c; >>> + int i, ret = 0; >>> + >>> + mutex_lock(&i2c->lock); >>> + >>> + /* Clear the EDID interrupt flag and unmute the interrupt */ >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY); >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); >>> + >>> + for (i = 0; i < num; i++) { >>> + dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", >>> + i + 1, num, msgs[i].len, msgs[i].flags); >>> + >>> + if (msgs[i].flags & I2C_M_RD) >>> + ret = inno_hdmi_i2c_read(hdmi, &msgs[i]); >>> + else >>> + ret = inno_hdmi_i2c_write(hdmi, &msgs[i]); >>> + >>> + if (ret < 0) >>> + break; >>> + } >>> + >>> + if (!ret) >>> + ret = num; >>> + >>> + /* Mute HDMI EDID interrupt */ >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); >>> + >>> + mutex_unlock(&i2c->lock); >>> + >>> + return ret; >>> +} >>> + >>> +static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter) >>> +{ >>> + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; >>> +} >>> + >>> +static const struct i2c_algorithm inno_hdmi_algorithm = { >>> + .master_xfer = inno_hdmi_i2c_xfer, >>> + .functionality = inno_hdmi_i2c_func, >>> +}; >>> + >>> +static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi >>> *hdmi) >>> +{ >>> + struct i2c_adapter *adap; >>> + struct inno_hdmi_i2c *i2c; >>> + int ret; >>> + >>> + i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); >>> + if (!i2c) >>> + return ERR_PTR(-ENOMEM); >>> + >>> + mutex_init(&i2c->lock); >>> + init_completion(&i2c->cmp); >>> + >>> + adap = &i2c->adap; >>> + adap->class = I2C_CLASS_DDC; >>> + adap->owner = THIS_MODULE; >>> + adap->dev.parent = hdmi->dev; >>> + adap->dev.of_node = hdmi->dev->of_node; >>> + adap->algo = &inno_hdmi_algorithm; >>> + strlcpy(adap->name, "Inno HDMI", sizeof(adap->name)); >>> + i2c_set_adapdata(adap, hdmi); >>> + >>> + ret = i2c_add_adapter(adap); >>> + if (ret) { >>> + dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", >>> adap->name); >>> + devm_kfree(hdmi->dev, i2c); >>> + return ERR_PTR(ret); >>> + } >>> + >>> + hdmi->i2c = i2c; >>> + >>> + dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); >>> + >>> + return adap; >>> +} >>> + >>> +static int inno_hdmi_bind(struct device *dev, struct device *master, >>> + void *data) >>> +{ >>> + struct platform_device *pdev = to_platform_device(dev); >>> + struct drm_device *drm = data; >>> + struct inno_hdmi *hdmi; >>> + struct resource *iores; >>> + int irq; >>> + int ret; >>> + >>> + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); >>> + if (!hdmi) >>> + return -ENOMEM; >>> + >>> + hdmi->dev = dev; >>> + hdmi->drm_dev = drm; >>> + >>> + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); >>> + if (!iores) >>> + return -ENXIO; >>> + >>> + hdmi->regs = devm_ioremap_resource(dev, iores); >>> + if (IS_ERR(hdmi->regs)) >>> + return PTR_ERR(hdmi->regs); >>> + >>> + hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); >>> + if (IS_ERR(hdmi->pclk)) { >>> + dev_err(hdmi->dev, "Unable to get HDMI pclk clk\n"); >>> + return PTR_ERR(hdmi->pclk); >>> + } >>> + >>> + ret = clk_prepare_enable(hdmi->pclk); >>> + if (ret) { >>> + dev_err(hdmi->dev, "Cannot enable HDMI pclk clock: %d\n", >>> ret); >>> + return ret; >>> + } >>> + >>> + irq = platform_get_irq(pdev, 0); >>> + if (irq < 0) >>> + return irq; >>> + >>> + inno_hdmi_reset(hdmi); >>> + >>> + hdmi->ddc = inno_hdmi_i2c_adapter(hdmi); >>> + if (IS_ERR(hdmi->ddc)) { >>> + hdmi->ddc = NULL; >>> + return PTR_ERR(hdmi->ddc); >>> + } >>> + >>> + /* >>> + * When IP controller haven't configured to an accurate video >>> + * timing, then the TMDS clock source would be switched to >>> + * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate, >>> + * and reconfigure the DDC clock. >>> + */ >>> + hdmi->tmds_rate = clk_get_rate(hdmi->pclk); >>> + inno_hdmi_i2c_init(hdmi); >>> + >>> + ret = inno_hdmi_register(drm, hdmi); >>> + if (ret) >>> + return ret; >>> + >>> + dev_set_drvdata(dev, hdmi); >>> + >>> + /* Unmute hotplug interrupt */ >>> + hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, >>> v_MASK_INT_HOTPLUG(1)); >>> + >>> + ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq, >>> + inno_hdmi_irq, IRQF_SHARED, >>> + dev_name(dev), hdmi); >>> + >>> + return ret; >>> +} >>> + >>> +static void inno_hdmi_unbind(struct device *dev, struct device >>> *master, >>> + void *data) >>> +{ >>> + struct inno_hdmi *hdmi = dev_get_drvdata(dev); >>> + >>> + hdmi->connector.funcs->destroy(&hdmi->connector); >>> + hdmi->encoder.funcs->destroy(&hdmi->encoder); >>> + >>> + clk_disable_unprepare(hdmi->pclk); >>> + i2c_put_adapter(hdmi->ddc); >>> +} >>> + >>> +static const struct component_ops inno_hdmi_ops = { >>> + .bind = inno_hdmi_bind, >>> + .unbind = inno_hdmi_unbind, >>> +}; >>> + >>> +static int inno_hdmi_probe(struct platform_device *pdev) >>> +{ >>> + return component_add(&pdev->dev, &inno_hdmi_ops); >>> +} >>> + >>> +static int inno_hdmi_remove(struct platform_device *pdev) >>> +{ >>> + component_del(&pdev->dev, &inno_hdmi_ops); >>> + >>> + return 0; >>> +} >>> + >>> +static const struct of_device_id inno_hdmi_dt_ids[] = { >>> + { .compatible = "rockchip,rk3036-inno-hdmi", >>> + }, >>> + {}, >>> +}; >>> +MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids); >>> + >>> +static struct platform_driver inno_hdmi_driver = { >>> + .probe = inno_hdmi_probe, >>> + .remove = inno_hdmi_remove, >>> + .driver = { >>> + .name = "innohdmi-rockchip", >>> + .of_match_table = inno_hdmi_dt_ids, >>> + }, >>> +}; >>> + >>> +module_platform_driver(inno_hdmi_driver); >>> + >>> +MODULE_AUTHOR("Zheng Yang "); >>> +MODULE_AUTHOR("Yakir Yang "); >>> +MODULE_DESCRIPTION("Rockchip Specific INNO-HDMI Driver"); >>> +MODULE_LICENSE("GPL"); >>> +MODULE_ALIAS("platform:innohdmi-rockchip"); >>> diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.h >>> b/drivers/gpu/drm/rockchip/inno_hdmi.h >>> new file mode 100644 >>> index 0000000..4ff17ad >>> --- /dev/null >>> +++ b/drivers/gpu/drm/rockchip/inno_hdmi.h >>> @@ -0,0 +1,364 @@ >>> +/* >>> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd >>> + * Zheng Yang >>> + * Yakir Yang >>> + * >>> + * This software is licensed under the terms of the GNU General Public >>> + * License version 2, as published by the Free Software Foundation, >>> and >>> + * may be copied, distributed, and modified under those terms. >>> + * >>> + * This program is distributed in the hope that it will be useful, >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >>> + * GNU General Public License for more details. >>> + */ >>> + >>> +#ifndef __INNO_HDMI_H__ >>> +#define __INNO_HDMI_H__ >>> + >>> +#define DDC_SEGMENT_ADDR 0x30 >>> + >>> +enum PWR_MODE { >>> + NORMAL, >>> + LOWER_PWR, >>> +}; >>> + >>> +#define HDMI_SCL_RATE (100*1000) >>> +#define DDC_BUS_FREQ_L 0x4b >>> +#define DDC_BUS_FREQ_H 0x4c >>> + >>> +#define HDMI_SYS_CTRL 0x00 >>> +#define m_RST_ANALOG (1 << 6) >>> +#define v_RST_ANALOG (0 << 6) >>> +#define v_NOT_RST_ANALOG (1 << 6) >>> +#define m_RST_DIGITAL (1 << 5) >>> +#define v_RST_DIGITAL (0 << 5) >>> +#define v_NOT_RST_DIGITAL (1 << 5) >>> +#define m_REG_CLK_INV (1 << 4) >>> +#define v_REG_CLK_NOT_INV (0 << 4) >>> +#define v_REG_CLK_INV (1 << 4) >>> +#define m_VCLK_INV (1 << 3) >>> +#define v_VCLK_NOT_INV (0 << 3) >>> +#define v_VCLK_INV (1 << 3) >>> +#define m_REG_CLK_SOURCE (1 << 2) >>> +#define v_REG_CLK_SOURCE_TMDS (0 << 2) >>> +#define v_REG_CLK_SOURCE_SYS (1 << 2) >>> +#define m_POWER (1 << 1) >>> +#define v_PWR_ON (0 << 1) >>> +#define v_PWR_OFF (1 << 1) >>> +#define m_INT_POL (1 << 0) >>> +#define v_INT_POL_HIGH 1 >>> +#define v_INT_POL_LOW 0 >>> + >>> +#define HDMI_VIDEO_CONTRL1 0x01 >>> +#define m_VIDEO_INPUT_FORMAT (7 << 1) >>> +#define m_DE_SOURCE (1 << 0) >>> +#define v_VIDEO_INPUT_FORMAT(n) (n << 1) >>> +#define v_DE_EXTERNAL 1 >>> +#define v_DE_INTERNAL 0 >>> +enum { >>> + VIDEO_INPUT_SDR_RGB444 = 0, >>> + VIDEO_INPUT_DDR_RGB444 = 5, >>> + VIDEO_INPUT_DDR_YCBCR422 = 6 >>> +}; >>> + >>> +#define HDMI_VIDEO_CONTRL2 0x02 >>> +#define m_VIDEO_OUTPUT_COLOR (3 << 6) >>> +#define m_VIDEO_INPUT_BITS (3 << 4) >>> +#define m_VIDEO_INPUT_CSP (1 << 0) >>> +#define v_VIDEO_OUTPUT_COLOR(n) (((n) & 0x3) << 6) >>> +#define v_VIDEO_INPUT_BITS(n) (n << 4) >>> +#define v_VIDEO_INPUT_CSP(n) (n << 0) >>> +enum { >>> + VIDEO_INPUT_12BITS = 0, >>> + VIDEO_INPUT_10BITS = 1, >>> + VIDEO_INPUT_REVERT = 2, >>> + VIDEO_INPUT_8BITS = 3, >>> +}; >>> + >>> +#define HDMI_VIDEO_CONTRL 0x03 >>> +#define m_VIDEO_AUTO_CSC (1 << 7) >>> +#define v_VIDEO_AUTO_CSC(n) (n << 7) >>> +#define m_VIDEO_C0_C2_SWAP (1 << 0) >>> +#define v_VIDEO_C0_C2_SWAP(n) (n << 0) >>> +enum { >>> + C0_C2_CHANGE_ENABLE = 0, >>> + C0_C2_CHANGE_DISABLE = 1, >>> + AUTO_CSC_DISABLE = 0, >>> + AUTO_CSC_ENABLE = 1, >>> +}; >>> + >>> +#define HDMI_VIDEO_CONTRL3 0x04 >>> +#define m_COLOR_DEPTH_NOT_INDICATED (1 << 4) >>> +#define m_SOF (1 << 3) >>> +#define m_COLOR_RANGE (1 << 2) >>> +#define m_CSC (1 << 0) >>> +#define v_COLOR_DEPTH_NOT_INDICATED(n) ((n) << 4) >>> +#define v_SOF_ENABLE (0 << 3) >>> +#define v_SOF_DISABLE (1 << 3) >>> +#define v_COLOR_RANGE_FULL (1 << 2) >>> +#define v_COLOR_RANGE_LIMITED (0 << 2) >>> +#define v_CSC_ENABLE 1 >>> +#define v_CSC_DISABLE 0 >>> + >>> +#define HDMI_AV_MUTE 0x05 >>> +#define m_AVMUTE_CLEAR (1 << 7) >>> +#define m_AVMUTE_ENABLE (1 << 6) >>> +#define m_AUDIO_MUTE (1 << 1) >>> +#define m_VIDEO_BLACK (1 << 0) >>> +#define v_AVMUTE_CLEAR(n) (n << 7) >>> +#define v_AVMUTE_ENABLE(n) (n << 6) >>> +#define v_AUDIO_MUTE(n) (n << 1) >>> +#define v_VIDEO_MUTE(n) (n << 0) >>> + >>> +#define HDMI_VIDEO_TIMING_CTL 0x08 >>> +#define v_HSYNC_POLARITY(n) (n << 3) >>> +#define v_VSYNC_POLARITY(n) (n << 2) >>> +#define v_INETLACE(n) (n << 1) >>> +#define v_EXTERANL_VIDEO(n) (n << 0) >>> + >>> +#define HDMI_VIDEO_EXT_HTOTAL_L 0x09 >>> +#define HDMI_VIDEO_EXT_HTOTAL_H 0x0a >>> +#define HDMI_VIDEO_EXT_HBLANK_L 0x0b >>> +#define HDMI_VIDEO_EXT_HBLANK_H 0x0c >>> +#define HDMI_VIDEO_EXT_HDELAY_L 0x0d >>> +#define HDMI_VIDEO_EXT_HDELAY_H 0x0e >>> +#define HDMI_VIDEO_EXT_HDURATION_L 0x0f >>> +#define HDMI_VIDEO_EXT_HDURATION_H 0x10 >>> +#define HDMI_VIDEO_EXT_VTOTAL_L 0x11 >>> +#define HDMI_VIDEO_EXT_VTOTAL_H 0x12 >>> +#define HDMI_VIDEO_EXT_VBLANK 0x13 >>> +#define HDMI_VIDEO_EXT_VDELAY 0x14 >>> +#define HDMI_VIDEO_EXT_VDURATION 0x15 >>> + >>> +#define HDMI_VIDEO_CSC_COEF 0x18 >>> + >>> +#define HDMI_AUDIO_CTRL1 0x35 >>> +enum { >>> + CTS_SOURCE_INTERNAL = 0, >>> + CTS_SOURCE_EXTERNAL = 1, >>> +}; >>> +#define v_CTS_SOURCE(n) (n << 7) >>> + >>> +enum { >>> + DOWNSAMPLE_DISABLE = 0, >>> + DOWNSAMPLE_1_2 = 1, >>> + DOWNSAMPLE_1_4 = 2, >>> +}; >>> +#define v_DOWN_SAMPLE(n) (n << 5) >>> + >>> +enum { >>> + AUDIO_SOURCE_IIS = 0, >>> + AUDIO_SOURCE_SPDIF = 1, >>> +}; >>> +#define v_AUDIO_SOURCE(n) (n << 3) >>> + >>> +#define v_MCLK_ENABLE(n) (n << 2) >>> +enum { >>> + MCLK_128FS = 0, >>> + MCLK_256FS = 1, >>> + MCLK_384FS = 2, >>> + MCLK_512FS = 3, >>> +}; >>> +#define v_MCLK_RATIO(n) (n) >>> + >>> +#define AUDIO_SAMPLE_RATE 0x37 >>> +enum { >>> + AUDIO_32K = 0x3, >>> + AUDIO_441K = 0x0, >>> + AUDIO_48K = 0x2, >>> + AUDIO_882K = 0x8, >>> + AUDIO_96K = 0xa, >>> + AUDIO_1764K = 0xc, >>> + AUDIO_192K = 0xe, >>> +}; >>> + >>> +#define AUDIO_I2S_MODE 0x38 >>> +enum { >>> + I2S_CHANNEL_1_2 = 1, >>> + I2S_CHANNEL_3_4 = 3, >>> + I2S_CHANNEL_5_6 = 7, >>> + I2S_CHANNEL_7_8 = 0xf >>> +}; >>> +#define v_I2S_CHANNEL(n) ((n) << 2) >>> +enum { >>> + I2S_STANDARD = 0, >>> + I2S_LEFT_JUSTIFIED = 1, >>> + I2S_RIGHT_JUSTIFIED = 2, >>> +}; >>> +#define v_I2S_MODE(n) (n) >>> + >>> +#define AUDIO_I2S_MAP 0x39 >>> +#define AUDIO_I2S_SWAPS_SPDIF 0x3a >>> +#define v_SPIDF_FREQ(n) (n) >>> + >>> +#define N_32K 0x1000 >>> +#define N_441K 0x1880 >>> +#define N_882K 0x3100 >>> +#define N_1764K 0x6200 >>> +#define N_48K 0x1800 >>> +#define N_96K 0x3000 >>> +#define N_192K 0x6000 >>> + >>> +#define HDMI_AUDIO_CHANNEL_STATUS 0x3e >>> +#define m_AUDIO_STATUS_NLPCM (1 << 7) >>> +#define m_AUDIO_STATUS_USE (1 << 6) >>> +#define m_AUDIO_STATUS_COPYRIGHT (1 << 5) >>> +#define m_AUDIO_STATUS_ADDITION (3 << 2) >>> +#define m_AUDIO_STATUS_CLK_ACCURACY (2 << 0) >>> +#define v_AUDIO_STATUS_NLPCM(n) ((n & 1) << 7) >>> +#define AUDIO_N_H 0x3f >>> +#define AUDIO_N_M 0x40 >>> +#define AUDIO_N_L 0x41 >>> + >>> +#define HDMI_AUDIO_CTS_H 0x45 >>> +#define HDMI_AUDIO_CTS_M 0x46 >>> +#define HDMI_AUDIO_CTS_L 0x47 >>> + >>> +#define HDMI_DDC_CLK_L 0x4b >>> +#define HDMI_DDC_CLK_H 0x4c >>> + >>> +#define HDMI_EDID_SEGMENT_POINTER 0x4d >>> +#define HDMI_EDID_WORD_ADDR 0x4e >>> +#define HDMI_EDID_FIFO_OFFSET 0x4f >>> +#define HDMI_EDID_FIFO_ADDR 0x50 >>> + >>> +#define HDMI_PACKET_SEND_MANUAL 0x9c >>> +#define HDMI_PACKET_SEND_AUTO 0x9d >>> +#define m_PACKET_GCP_EN (1 << 7) >>> +#define m_PACKET_MSI_EN (1 << 6) >>> +#define m_PACKET_SDI_EN (1 << 5) >>> +#define m_PACKET_VSI_EN (1 << 4) >>> +#define v_PACKET_GCP_EN(n) ((n & 1) << 7) >>> +#define v_PACKET_MSI_EN(n) ((n & 1) << 6) >>> +#define v_PACKET_SDI_EN(n) ((n & 1) << 5) >>> +#define v_PACKET_VSI_EN(n) ((n & 1) << 4) >>> + >>> +#define HDMI_CONTROL_PACKET_BUF_INDEX 0x9f >>> +enum { >>> + INFOFRAME_VSI = 0x05, >>> + INFOFRAME_AVI = 0x06, >>> + INFOFRAME_AAI = 0x08, >>> +}; >>> + >>> +#define HDMI_CONTROL_PACKET_ADDR 0xa0 >>> +#define HDMI_SIZE_VSI_INFOFRAME 0x0A >>> +#define HDMI_SIZE_AVI_INFOFRAME 0x11 >>> +#define HDMI_SIZE_AUDIO_INFOFRAME 0x0F >>> +enum { >>> + AVI_COLOR_MODE_RGB = 0, >>> + AVI_COLOR_MODE_YCBCR422 = 1, >>> + AVI_COLOR_MODE_YCBCR444 = 2, >>> + AVI_COLORIMETRY_NO_DATA = 0, >>> + >>> + AVI_COLORIMETRY_SMPTE_170M = 1, >>> + AVI_COLORIMETRY_ITU709 = 2, >>> + AVI_COLORIMETRY_EXTENDED = 3, >>> + >>> + AVI_CODED_FRAME_ASPECT_NO_DATA = 0, >>> + AVI_CODED_FRAME_ASPECT_4_3 = 1, >>> + AVI_CODED_FRAME_ASPECT_16_9 = 2, >>> + >>> + ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, >>> + ACTIVE_ASPECT_RATE_4_3 = 0x09, >>> + ACTIVE_ASPECT_RATE_16_9 = 0x0A, >>> + ACTIVE_ASPECT_RATE_14_9 = 0x0B, >>> +}; >>> + >>> +#define HDMI_HDCP_CTRL 0x52 >>> +#define m_HDMI_DVI (1 << 1) >>> +#define v_HDMI_DVI(n) (n << 1) >>> + >>> +#define HDMI_INTERRUPT_MASK1 0xc0 >>> +#define HDMI_INTERRUPT_STATUS1 0xc1 >>> +#define m_INT_ACTIVE_VSYNC (1 << 5) >>> +#define m_INT_EDID_READY (1 << 2) >>> + >>> +#define HDMI_INTERRUPT_MASK2 0xc2 >>> +#define HDMI_INTERRUPT_STATUS2 0xc3 >>> +#define m_INT_HDCP_ERR (1 << 7) >>> +#define m_INT_BKSV_FLAG (1 << 6) >>> +#define m_INT_HDCP_OK (1 << 4) >>> + >>> +#define HDMI_STATUS 0xc8 >>> +#define m_HOTPLUG (1 << 7) >>> +#define m_MASK_INT_HOTPLUG (1 << 5) >>> +#define m_INT_HOTPLUG (1 << 1) >>> +#define v_MASK_INT_HOTPLUG(n) ((n & 0x1) << 5) >>> + >>> +#define HDMI_COLORBAR 0xc9 >>> + >>> +#define HDMI_PHY_SYNC 0xce >>> +#define HDMI_PHY_SYS_CTL 0xe0 >>> +#define m_TMDS_CLK_SOURCE (1 << 5) >>> +#define v_TMDS_FROM_PLL (0 << 5) >>> +#define v_TMDS_FROM_GEN (1 << 5) >>> +#define m_PHASE_CLK (1 << 4) >>> +#define v_DEFAULT_PHASE (0 << 4) >>> +#define v_SYNC_PHASE (1 << 4) >>> +#define m_TMDS_CURRENT_PWR (1 << 3) >>> +#define v_TURN_ON_CURRENT (0 << 3) >>> +#define v_CAT_OFF_CURRENT (1 << 3) >>> +#define m_BANDGAP_PWR (1 << 2) >>> +#define v_BANDGAP_PWR_UP (0 << 2) >>> +#define v_BANDGAP_PWR_DOWN (1 << 2) >>> +#define m_PLL_PWR (1 << 1) >>> +#define v_PLL_PWR_UP (0 << 1) >>> +#define v_PLL_PWR_DOWN (1 << 1) >>> +#define m_TMDS_CHG_PWR (1 << 0) >>> +#define v_TMDS_CHG_PWR_UP (0 << 0) >>> +#define v_TMDS_CHG_PWR_DOWN (1 << 0) >>> + >>> +#define HDMI_PHY_CHG_PWR 0xe1 >>> +#define v_CLK_CHG_PWR(n) ((n & 1) << 3) >>> +#define v_DATA_CHG_PWR(n) ((n & 7) << 0) >>> + >>> +#define HDMI_PHY_DRIVER 0xe2 >>> +#define v_CLK_MAIN_DRIVER(n) (n << 4) >>> +#define v_DATA_MAIN_DRIVER(n) (n << 0) >>> + >>> +#define HDMI_PHY_PRE_EMPHASIS 0xe3 >>> +#define v_PRE_EMPHASIS(n) ((n & 7) << 4) >>> +#define v_CLK_PRE_DRIVER(n) ((n & 3) << 2) >>> +#define v_DATA_PRE_DRIVER(n) ((n & 3) << 0) >>> + >>> +#define HDMI_PHY_FEEDBACK_DIV_RATIO_LOW 0xe7 >>> +#define v_FEEDBACK_DIV_LOW(n) (n & 0xff) >>> +#define HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH 0xe8 >>> +#define v_FEEDBACK_DIV_HIGH(n) (n & 1) >>> + >>> +#define HDMI_PHY_PRE_DIV_RATIO 0xed >>> +#define v_PRE_DIV_RATIO(n) (n & 0x1f) >>> + >>> +#define HDMI_CEC_CTRL 0xd0 >>> +#define m_ADJUST_FOR_HISENSE (1 << 6) >>> +#define m_REJECT_RX_BROADCAST (1 << 5) >>> +#define m_BUSFREETIME_ENABLE (1 << 2) >>> +#define m_REJECT_RX (1 << 1) >>> +#define m_START_TX (1 << 0) >>> + >>> +#define HDMI_CEC_DATA 0xd1 >>> +#define HDMI_CEC_TX_OFFSET 0xd2 >>> +#define HDMI_CEC_RX_OFFSET 0xd3 >>> +#define HDMI_CEC_CLK_H 0xd4 >>> +#define HDMI_CEC_CLK_L 0xd5 >>> +#define HDMI_CEC_TX_LENGTH 0xd6 >>> +#define HDMI_CEC_RX_LENGTH 0xd7 >>> +#define HDMI_CEC_TX_INT_MASK 0xd8 >>> +#define m_TX_DONE (1 << 3) >>> +#define m_TX_NOACK (1 << 2) >>> +#define m_TX_BROADCAST_REJ (1 << 1) >>> +#define m_TX_BUSNOTFREE (1 << 0) >>> + >>> +#define HDMI_CEC_RX_INT_MASK 0xd9 >>> +#define m_RX_LA_ERR (1 << 4) >>> +#define m_RX_GLITCH (1 << 3) >>> +#define m_RX_DONE (1 << 0) >>> + >>> +#define HDMI_CEC_TX_INT 0xda >>> +#define HDMI_CEC_RX_INT 0xdb >>> +#define HDMI_CEC_BUSFREETIME_L 0xdc >>> +#define HDMI_CEC_BUSFREETIME_H 0xdd >>> +#define HDMI_CEC_LOGICADDR 0xde >>> + >>> +#endif /* __INNO_HDMI_H__ */ >> >> > > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753933AbcAYBWm (ORCPT ); Sun, 24 Jan 2016 20:22:42 -0500 Received: from lucky1.263xmail.com ([211.157.147.130]:49776 "EHLO lucky1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751763AbcAYBWh (ORCPT ); Sun, 24 Jan 2016 20:22:37 -0500 X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 X-RL-SENDER: ykk@rock-chips.com X-FST-TO: linux-arm-kernel@lists.infradead.org X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: ykk@rock-chips.com X-UNIQUE-TAG: X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 Subject: Re: [PATCH v3 1/2] drm: rockchip/hdmi: add Innosilicon HDMI support To: Caesar Wang References: <1452850598-30859-1-git-send-email-ykk@rock-chips.com> <1452850690-31760-1-git-send-email-ykk@rock-chips.com> <569C3E36.10103@rock-chips.com> <56A47E6F.8050104@gmail.com> Cc: Mark yao , Heiko Stuebner , devicetree@vger.kernel.org, David Airlie , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-rockchip@lists.infradead.org, Rob Herring , Thierry Reding , linux-arm-kernel@lists.infradead.org From: Yakir Yang Message-ID: <56A578D7.5070101@rock-chips.com> Date: Mon, 25 Jan 2016 09:22:31 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56A47E6F.8050104@gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Caesar, On 01/24/2016 03:34 PM, Caesar Wang wrote: > Hi > > 在 2016年01月18日 09:21, Mark yao 写道: >> Hi Yakir >> >> I'd like you can change your patch title into "drm/rockchip/hdmi", so >> when I search patches use "drm/rockchip" can find your patch. >> >> and I have some advices mail inline. >> >> Thanks:-) >> >> On 2016年01月15日 17:38, Yakir Yang wrote: >>> The Innosilicon HDMI is a low power HDMI 1.4 transmitter >>> IP, and it have been integrated on some rockchip CPUs >>> (like RK3036, RK312x). >>> >>> Signed-off-by: Yakir Yang >>> --- >>> Changes in v3: >>> - Use encoder enable/disable function, and remove the encoder DPMS >>> function >>> - Keep HDMI PLL power on in standby mode >>> >>> Changes in v2: >>> - Using DRM atomic helper functions for connector init (Mark) >>> - Remove "hdmi->connector.encoder = encoder;" (Mark) >>> >>> drivers/gpu/drm/rockchip/Kconfig | 8 + >>> drivers/gpu/drm/rockchip/Makefile | 1 + >>> drivers/gpu/drm/rockchip/inno_hdmi.c | 999 >>> +++++++++++++++++++++++++++++++++++ >>> drivers/gpu/drm/rockchip/inno_hdmi.h | 364 +++++++++++++ >>> 4 files changed, 1372 insertions(+) >>> create mode 100644 drivers/gpu/drm/rockchip/inno_hdmi.c >>> create mode 100644 drivers/gpu/drm/rockchip/inno_hdmi.h >>> >>> diff --git a/drivers/gpu/drm/rockchip/Kconfig >>> b/drivers/gpu/drm/rockchip/Kconfig >>> index 35215f6..a5014e0 100644 >>> --- a/drivers/gpu/drm/rockchip/Kconfig >>> +++ b/drivers/gpu/drm/rockchip/Kconfig >>> @@ -25,3 +25,11 @@ config ROCKCHIP_DW_HDMI >>> for the Synopsys DesignWare HDMI driver. If you want to >>> enable HDMI on RK3288 based SoC, you should selet this >>> option. >>> + >>> +config ROCKCHIP_INNO_HDMI >>> + tristate "Rockchip specific extensions for Innosilicon HDMI" >>> + depends on DRM_ROCKCHIP >>> + help >>> + This selects support for Rockchip SoC specific extensions >>> + for the Innosilicon HDMI driver. If you want to enable >>> + HDMI on RK3036 based SoC, you should selet this option. > > That's seem has some conflicts since the MIPI driver land in mainline. > So you need update it based on the lastest kernel. > Yep, thanks for your reminder, need to update the patch. And by the way the latest version of this patch have been updated to v5 :) https://patchwork.kernel.org/patch/8058061/ >>> diff --git a/drivers/gpu/drm/rockchip/Makefile >>> b/drivers/gpu/drm/rockchip/Makefile >>> index a9d380f..da2bf76 100644 >>> --- a/drivers/gpu/drm/rockchip/Makefile >>> +++ b/drivers/gpu/drm/rockchip/Makefile >>> @@ -6,6 +6,7 @@ rockchipdrm-y := rockchip_drm_drv.o >>> rockchip_drm_fb.o rockchip_drm_fbdev.o \ >>> rockchip_drm_gem.o >>> obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o >>> +obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o >>> obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o \ >>> rockchip_vop_reg.o >>> diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c >>> b/drivers/gpu/drm/rockchip/inno_hdmi.c >>> new file mode 100644 >>> index 0000000..dc98179 >>> --- /dev/null >>> +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c >>> @@ -0,0 +1,999 @@ >>> +/* >>> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd >>> + * Zheng Yang >>> + * Yakir Yang >>> + * >>> + * This software is licensed under the terms of the GNU General Public >>> + * License version 2, as published by the Free Software Foundation, >>> and >>> + * may be copied, distributed, and modified under those terms. >>> + * >>> + * This program is distributed in the hope that it will be useful, >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >>> + * GNU General Public License for more details. >>> + */ >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include "rockchip_drm_drv.h" >>> +#include "rockchip_drm_vop.h" >>> + >>> +#include "inno_hdmi.h" >>> + >>> +#define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x) >>> + >>> +struct hdmi_data_info { >>> + int vic; >>> + bool sink_is_hdmi; >>> + bool sink_has_audio; >>> + unsigned int enc_in_format; >>> + unsigned int enc_out_format; >>> + unsigned int colorimetry; >>> +}; >>> + >>> +struct inno_hdmi_i2c { >>> + struct i2c_adapter adap; >>> + >>> + u8 ddc_addr; >>> + u8 segment_addr; >>> + >>> + struct mutex lock; >>> + struct completion cmp; >>> +}; >>> + >>> +struct inno_hdmi { >>> + struct device *dev; >>> + struct drm_device *drm_dev; >>> + >>> + int irq; >>> + struct clk *pclk; >>> + void __iomem *regs; >>> + >>> + struct drm_connector connector; >>> + struct drm_encoder encoder; >>> + >>> + struct inno_hdmi_i2c *i2c; >>> + struct i2c_adapter *ddc; >>> + >>> + unsigned int tmds_rate; >>> + >>> + struct hdmi_data_info hdmi_data; >>> + struct drm_display_mode previous_mode; >>> +}; >>> + >>> +enum { >>> + CSC_ITU601_16_235_TO_RGB_0_255_8BIT, >>> + CSC_ITU601_0_255_TO_RGB_0_255_8BIT, >>> + CSC_ITU709_16_235_TO_RGB_0_255_8BIT, >>> + CSC_RGB_0_255_TO_ITU601_16_235_8BIT, >>> + CSC_RGB_0_255_TO_ITU709_16_235_8BIT, >>> + CSC_RGB_0_255_TO_RGB_16_235_8BIT, >>> +}; >>> + >>> +static const char coeff_csc[][24] = { >>> + /* >>> + * YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]): >>> + * R = 1.164*Y + 1.596*V - 204 >>> + * G = 1.164*Y - 0.391*U - 0.813*V + 154 >>> + * B = 1.164*Y + 2.018*U - 258 >>> + */ >>> + { >>> + 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc, >>> + 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a, >>> + 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02 >>> + }, >>> + /* >>> + * YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]): >>> + * R = Y + 1.402*V - 248 >>> + * G = Y - 0.344*U - 0.714*V + 135 >>> + * B = Y + 1.772*U - 227 >>> + */ >>> + { >>> + 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8, >>> + 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87, >>> + 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3 >>> + }, >>> + /* >>> + * YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]): >>> + * R = 1.164*Y + 1.793*V - 248 >>> + * G = 1.164*Y - 0.213*U - 0.534*V + 77 >>> + * B = 1.164*Y + 2.115*U - 289 >>> + */ >>> + { >>> + 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8, >>> + 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d, >>> + 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21 >>> + }, >>> + >>> + /* >>> + * RGB2YUV:601 SD mode: >>> + * Cb = -0.291G - 0.148R + 0.439B + 128 >>> + * Y = 0.504G + 0.257R + 0.098B + 16 >>> + * Cr = -0.368G + 0.439R - 0.071B + 128 >>> + */ >>> + { >>> + 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80, >>> + 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e, >>> + 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80 >>> + }, >>> + /* >>> + * RGB2YUV:709 HD mode: >>> + * Cb = - 0.338G - 0.101R + 0.439B + 128 >>> + * Y = 0.614G + 0.183R + 0.062B + 16 >>> + * Cr = - 0.399G + 0.439R - 0.040B + 128 >>> + */ >>> + { >>> + 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80, >>> + 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10, >>> + 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80 >>> + }, >>> + /* >>> + * RGB[0:255]2RGB[16:235]: >>> + * R' = R x (235-16)/255 + 16; >>> + * G' = G x (235-16)/255 + 16; >>> + * B' = B x (235-16)/255 + 16; >>> + */ >>> + { >>> + 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10, >>> + 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, >>> + 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10 >>> + }, >>> +}; >>> + >>> +static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset) >>> +{ >>> + return readl_relaxed(hdmi->regs + (offset) * 0x04); >>> +} >>> + >>> +static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, >>> u32 val) >>> +{ >>> + writel_relaxed(val, hdmi->regs + (offset) * 0x04); >>> +} >>> + >>> +static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset, >>> + u32 msk, u32 val) >>> +{ >>> + u8 temp = hdmi_readb(hdmi, offset) & ~msk; >>> + >>> + temp |= val & msk; >>> + hdmi_writeb(hdmi, offset, temp); >>> +} >>> + >>> +static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi) >>> +{ >>> + int ddc_bus_freq; >>> + >>> + ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE; >>> + >>> + hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); >>> + hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); >>> + >>> + /* Clear the EDID interrupt flag and mute the interrupt */ >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); >>> +} >>> + >>> +static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable) >>> +{ >>> + if (enable) >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON); >>> + else >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF); >>> +} >>> + >>> +static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode) >>> +{ >>> + switch (mode) { >>> + case NORMAL: >>> + inno_hdmi_sys_power(hdmi, false); >>> + >>> + hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f); >>> + hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb); >>> + >>> + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10); >>> + hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01); >>> + >>> + inno_hdmi_sys_power(hdmi, true); >>> + break; >>> + >>> + case LOWER_PWR: >>> + inno_hdmi_sys_power(hdmi, false); >>> + hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00); >>> + hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00); >>> + hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00); >>> + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); >>> + >>> + break; >>> + >>> + default: >>> + dev_err(hdmi->dev, "Unknown power mode %d\n", mode); >>> + } >>> +} >>> + >>> +static void inno_hdmi_reset(struct inno_hdmi *hdmi) >>> +{ >>> + u32 val; >>> + u32 msk; >>> + >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL); >>> + udelay(100); >>> + >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG); >>> + udelay(100); >>> + >>> + msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL; >>> + val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | >>> v_INT_POL_HIGH; >>> + hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val); >>> + >>> + inno_hdmi_set_pwr_mode(hdmi, NORMAL); >>> +} >>> + >>> +static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi) >>> +{ >>> + char info[HDMI_SIZE_AVI_INFOFRAME] = {0}; >>> + int avi_color_mode; >>> + int i; >>> + >>> + hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); >>> + >>> + info[0] = 0x82; >>> + info[1] = 0x02; >>> + info[2] = 0x0D; >>> + info[3] = info[0] + info[1] + info[2]; >>> + >>> + if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_RGB) >>> + avi_color_mode = AVI_COLOR_MODE_RGB; >>> + else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444) >>> + avi_color_mode = AVI_COLOR_MODE_YCBCR444; >>> + else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422) >>> + avi_color_mode = AVI_COLOR_MODE_YCBCR422; >>> + else >>> + avi_color_mode = AVI_COLOR_MODE_RGB; >>> + >>> + info[4] = (avi_color_mode << 5); >>> + info[5] = (AVI_COLORIMETRY_NO_DATA << 6) | >>> + (AVI_CODED_FRAME_ASPECT_NO_DATA << 4) | >>> + ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME; >>> + >>> + info[6] = 0; >>> + info[7] = hdmi->hdmi_data.vic; >>> + >>> + if (hdmi->hdmi_data.vic == 6 || hdmi->hdmi_data.vic == 7 || >>> + hdmi->hdmi_data.vic == 21 || hdmi->hdmi_data.vic == 22) >>> + info[8] = 1; >>> + else >>> + info[8] = 0; >>> + >>> + /* Calculate avi info frame checKsum */ >>> + for (i = 4; i < HDMI_SIZE_AVI_INFOFRAME; i++) >>> + info[3] += info[i]; >>> + info[3] = 0x100 - info[3]; >>> + >>> + for (i = 0; i < HDMI_SIZE_AVI_INFOFRAME; i++) >>> + hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, info[i]); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi) >>> +{ >>> + char info[HDMI_SIZE_VSI_INFOFRAME] = {0}; >>> + int i; >>> + >>> + hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, m_PACKET_VSI_EN, >>> + v_PACKET_VSI_EN(0)); >>> + >>> + hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_VSI); >>> + >>> + /* Header Bytes */ >>> + info[0] = 0x81; >>> + info[1] = 0x01; >>> + >>> + /* PB1 - PB3 contain the 24bit IEEE Registration Identifier */ >>> + info[4] = 0x03; >>> + info[5] = 0x0c; >>> + info[6] = 0x00; >>> + >>> + /* PB4 - HDMI_Video_Format into bits 7:5 */ >>> + info[7] = 0; >>> + >>> + /* >>> + * PB5 - Depending on the video format, this byte will contain >>> + * either the HDMI_VIC code in buts 7:0, OR the 3D_Structure in >>> + * bits 7:4. >>> + */ >>> + info[2] = 0x06 - 2; >>> + info[8] = 0; >>> + info[9] = 0; >>> + >>> + info[3] = info[0] + info[1] + info[2]; >>> + >>> + /* Calculate info frame checKsum */ >>> + for (i = 4; i < HDMI_SIZE_VSI_INFOFRAME; i++) >>> + info[3] += info[i]; >>> + info[3] = 0x100 - info[3]; >>> + >>> + for (i = 0; i < HDMI_SIZE_VSI_INFOFRAME; i++) >>> + hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, info[i]); >>> + >>> + hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, m_PACKET_VSI_EN, >>> + v_PACKET_VSI_EN(1)); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) >>> +{ >>> + struct hdmi_data_info *data = &hdmi->hdmi_data; >>> + int c0_c2_change = 0; >>> + int csc_enable = 0; >>> + int csc_mode = 0; >>> + int auto_csc = 0; >>> + int value; >>> + int i; >>> + >>> + /* Input video mode is SDR RGB24bit, data enable signal from >>> external */ >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL | >>> + v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444)); >>> + >>> + /* Input color hardcode to RGB, and output color hardcode to >>> RGB888 */ >>> + value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | >>> + v_VIDEO_OUTPUT_COLOR(0) | >>> + v_VIDEO_INPUT_CSP(0); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value); >>> + >>> + if (data->enc_out_format == data->enc_out_format) { >>> + if ((data->enc_in_format == HDMI_COLORSPACE_RGB) || >>> + (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) { >>> + value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); >>> + >>> + hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, >>> + m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP, >>> + v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) | >>> + v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE)); >>> + return 0; >>> + } >>> + } >>> + >>> + if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) { >>> + if ((data->enc_in_format == HDMI_COLORSPACE_RGB) && >>> + (data->enc_out_format == HDMI_COLORSPACE_YUV444)) { >>> + csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT; >>> + auto_csc = AUTO_CSC_DISABLE; >>> + c0_c2_change = C0_C2_CHANGE_DISABLE; >>> + csc_enable = v_CSC_ENABLE; >>> + } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) && >>> + (data->enc_out_format == HDMI_COLORSPACE_RGB)) { >>> + csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; >>> + auto_csc = AUTO_CSC_ENABLE; >>> + c0_c2_change = C0_C2_CHANGE_DISABLE; >>> + csc_enable = v_CSC_DISABLE; >>> + } >>> + } else { >>> + if ((data->enc_in_format == HDMI_COLORSPACE_RGB) && >>> + (data->enc_out_format == HDMI_COLORSPACE_YUV444)) { >>> + csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT; >>> + auto_csc = AUTO_CSC_DISABLE; >>> + c0_c2_change = C0_C2_CHANGE_DISABLE; >>> + csc_enable = v_CSC_ENABLE; >>> + } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) && >>> + (data->enc_out_format == HDMI_COLORSPACE_RGB)) { >>> + csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT; >>> + auto_csc = AUTO_CSC_ENABLE; >>> + c0_c2_change = C0_C2_CHANGE_DISABLE; >>> + csc_enable = v_CSC_DISABLE; >>> + } >>> + } >>> + >>> + for (i = 0; i < 24; i++) >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i, >>> + coeff_csc[csc_mode][i]); >>> + >>> + value = v_SOF_DISABLE | csc_enable | >>> v_COLOR_DEPTH_NOT_INDICATED(1); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); >>> + hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC | >>> + m_VIDEO_C0_C2_SWAP, v_VIDEO_AUTO_CSC(auto_csc) | >>> + v_VIDEO_C0_C2_SWAP(c0_c2_change)); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, >>> + struct drm_display_mode *mode) >>> +{ >>> + int value; >>> + >>> + /* Set detail external video timing polarity and interlace mode */ >>> + value = v_EXTERANL_VIDEO(1); >>> + value |= mode->flags & DRM_MODE_FLAG_PHSYNC ? >>> + v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0); >>> + value |= mode->flags & DRM_MODE_FLAG_PVSYNC ? >>> + v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0); >>> + value |= mode->flags & DRM_MODE_FLAG_INTERLACE ? >>> + v_INETLACE(1) : v_INETLACE(0); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value); >>> + >>> + /* Set detail external video timing */ >>> + value = mode->htotal; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); >>> + >>> + value = mode->htotal - mode->hdisplay; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); >>> + >>> + value = mode->hsync_start - mode->hdisplay; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); >>> + >>> + value = mode->hsync_end - mode->hsync_start; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & >>> 0xFF); >>> + >>> + value = mode->vtotal; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF); >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); >>> + >>> + value = mode->vtotal - mode->vdisplay; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF); >>> + >>> + value = mode->vsync_start - mode->vdisplay; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF); >>> + >>> + value = mode->vsync_end - mode->vsync_start; >>> + hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF); >>> + >>> + hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e); >>> + hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c); >>> + hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_setup(struct inno_hdmi *hdmi, >>> + struct drm_display_mode *mode) >>> +{ >>> + int value; > > Where be used? > I guess you should remove it. > > > > - > Caesar >>> + >>> + hdmi->hdmi_data.vic = drm_match_cea_mode(mode); >>> + >>> + hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB; >>> + hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB; >>> + >>> + if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) || >>> + (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) || >>> + (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) || >>> + (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18)) >>> + hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; >>> + else >>> + hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; >>> + >>> + /* Mute video and audio output */ >>> + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, >>> + v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); >>> + >>> + /* Set HDMI Mode */ >>> + hdmi_writeb(hdmi, HDMI_HDCP_CTRL, >>> + v_HDMI_DVI(hdmi->hdmi_data.sink_is_hdmi)); >>> + >>> + inno_hdmi_config_video_timing(hdmi, mode); >>> + >>> + inno_hdmi_config_video_csc(hdmi); >>> + >>> + if (hdmi->hdmi_data.sink_is_hdmi) { >>> + inno_hdmi_config_video_avi(hdmi); >>> + inno_hdmi_config_video_vsi(hdmi); >>> + } >>> + >>> + /* >>> + * When IP controller have configured to an accurate video >>> + * timing, then the TMDS clock source would be switched to >>> + * DCLK_LCDC, so we need to init the TMDS rate to mode pixel >>> + * clock rate, and reconfigure the DDC clock. >>> + */ >>> + hdmi->tmds_rate = mode->clock * 1000; >>> + inno_hdmi_i2c_init(hdmi); >>> + >>> + /* Unmute video and audio output */ >>> + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, >>> + v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); >>> + >>> + return 0; >>> +} >>> + >>> +static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder, >>> + struct drm_display_mode *mode, >>> + struct drm_display_mode *adj_mode) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(encoder); >>> + >>> + inno_hdmi_setup(hdmi, adj_mode); >>> + >>> + /* Store the display mode for plugin/DKMS poweron events */ >> >> I think DKMS should be DPMS. >> >>> + memcpy(&hdmi->previous_mode, adj_mode, >>> sizeof(hdmi->previous_mode)); >>> +} >>> + >>> +static void inno_hdmi_encoder_enable(struct drm_encoder *encoder) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(encoder); >>> + >>> + inno_hdmi_set_pwr_mode(hdmi, NORMAL); >>> +} >>> + >>> +static void inno_hdmi_encoder_disable(struct drm_encoder *encoder) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(encoder); >>> + >>> + inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR); >>> +} >>> + >>> +static void inno_hdmi_encoder_commit(struct drm_encoder *encoder) >>> +{ >>> +} >>> + >>> +static void inno_hdmi_encoder_prepare(struct drm_encoder *encoder) >>> +{ >>> + rockchip_drm_crtc_mode_config(encoder->crtc, >>> DRM_MODE_CONNECTOR_HDMIA, >>> + ROCKCHIP_OUT_MODE_P888); >> >> Can you move mode_config into inno_hdmi_encoder_enable, and remove >> .prepare and .commit? >> >>> +} >>> + >>> +static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder, >>> + const struct drm_display_mode *mode, >>> + struct drm_display_mode *adj_mode) >>> +{ >>> + return true; >>> +} >>> + >>> +static struct drm_encoder_helper_funcs >>> inno_hdmi_encoder_helper_funcs = { >>> + .enable = inno_hdmi_encoder_enable, >>> + .disable = inno_hdmi_encoder_disable, >>> + .mode_fixup = inno_hdmi_encoder_mode_fixup, >>> + .mode_set = inno_hdmi_encoder_mode_set, >>> + .prepare = inno_hdmi_encoder_prepare, >>> + .commit = inno_hdmi_encoder_commit, >> >> On drm atomic, I think if support .enable and .disable callbacks, >> then .prepare and .commit is not needed. >> >>> +}; >>> + >>> +static struct drm_encoder_funcs inno_hdmi_encoder_funcs = { >>> + .destroy = drm_encoder_cleanup, >>> +}; >>> + >>> +static enum drm_connector_status >>> +inno_hdmi_connector_detect(struct drm_connector *connector, bool >>> force) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(connector); >>> + >>> + return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ? >>> + connector_status_connected : connector_status_disconnected; >>> +} >>> + >>> +static int inno_hdmi_connector_get_modes(struct drm_connector >>> *connector) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(connector); >>> + struct edid *edid; >>> + int ret = 0; >>> + >>> + if (!hdmi->ddc) >>> + return 0; >>> + >>> + edid = drm_get_edid(connector, hdmi->ddc); >>> + if (edid) { >>> + hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid); >>> + hdmi->hdmi_data.sink_has_audio = >>> drm_detect_monitor_audio(edid); >>> + drm_mode_connector_update_edid_property(connector, edid); >>> + ret = drm_add_edid_modes(connector, edid); >>> + kfree(edid); >>> + } >>> + >>> + return ret; >>> +} >>> + >>> +static enum drm_mode_status >>> +inno_hdmi_connector_mode_valid(struct drm_connector *connector, >>> + struct drm_display_mode *mode) >>> +{ >>> + return MODE_OK; >>> +} >>> + >>> +static struct drm_encoder * >>> +inno_hdmi_connector_best_encoder(struct drm_connector *connector) >>> +{ >>> + struct inno_hdmi *hdmi = to_inno_hdmi(connector); >>> + >>> + return &hdmi->encoder; >>> +} >>> + >>> +static int >>> +inno_hdmi_probe_single_connector_modes(struct drm_connector >>> *connector, >>> + uint32_t maxX, uint32_t maxY) >>> +{ >>> + return drm_helper_probe_single_connector_modes(connector, 1920, >>> 1080); >>> +} >>> + >>> +static void inno_hdmi_connector_destroy(struct drm_connector >>> *connector) >>> +{ >>> + drm_connector_unregister(connector); >>> + drm_connector_cleanup(connector); >>> +} >>> + >>> +static struct drm_connector_funcs inno_hdmi_connector_funcs = { >>> + .dpms = drm_atomic_helper_connector_dpms, >>> + .fill_modes = inno_hdmi_probe_single_connector_modes, >>> + .detect = inno_hdmi_connector_detect, >>> + .destroy = inno_hdmi_connector_destroy, >>> + .reset = drm_atomic_helper_connector_reset, >>> + .atomic_duplicate_state = >>> drm_atomic_helper_connector_duplicate_state, >>> + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, >>> +}; >>> + >>> +static struct drm_connector_helper_funcs >>> inno_hdmi_connector_helper_funcs = { >>> + .get_modes = inno_hdmi_connector_get_modes, >>> + .mode_valid = inno_hdmi_connector_mode_valid, >>> + .best_encoder = inno_hdmi_connector_best_encoder, >>> +}; >>> + >>> +static int inno_hdmi_register(struct drm_device *drm, struct >>> inno_hdmi *hdmi) >>> +{ >>> + struct drm_encoder *encoder = &hdmi->encoder; >>> + >>> + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, >>> hdmi->dev->of_node); >> >> Keep 80 characters :-) . >> >>> + /* >>> + * If we failed to find the CRTC(s) which this encoder is >>> + * supposed to be connected to, it's because the CRTC has >>> + * not been registered yet. Defer probing, and hope that >>> + * the required CRTC is added later. >>> + */ >>> + if (encoder->possible_crtcs == 0) >>> + return -EPROBE_DEFER; >>> + >>> + drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs); >>> + drm_encoder_init(drm, encoder, &inno_hdmi_encoder_funcs, >>> + DRM_MODE_ENCODER_TMDS, NULL); >>> + >>> + hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; >>> + >>> + drm_connector_helper_add(&hdmi->connector, >>> + &inno_hdmi_connector_helper_funcs); >>> + drm_connector_init(drm, &hdmi->connector, >>> &inno_hdmi_connector_funcs, >>> + DRM_MODE_CONNECTOR_HDMIA); >>> + >>> + drm_mode_connector_attach_encoder(&hdmi->connector, encoder); >>> + >>> + return 0; >>> +} >>> + >>> +static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi) >>> +{ >>> + struct inno_hdmi_i2c *i2c = hdmi->i2c; >>> + u8 stat; >>> + >>> + stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1); >>> + if (!(stat & m_INT_EDID_READY)) >>> + return IRQ_NONE; >>> + >>> + /* Clear HDMI EDID interrupt flag */ >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); >>> + >>> + complete(&i2c->cmp); >>> + >>> + return IRQ_HANDLED; >>> +} >>> + >>> +static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id) >>> +{ >>> + struct inno_hdmi *hdmi = dev_id; >>> + irqreturn_t ret = IRQ_NONE; >>> + u8 interrupt; >>> + >>> + if (hdmi->i2c) >>> + ret = inno_hdmi_i2c_irq(hdmi); >>> + >>> + interrupt = hdmi_readb(hdmi, HDMI_STATUS); >>> + if (interrupt & m_INT_HOTPLUG) { >>> + hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG); >>> + ret = IRQ_WAKE_THREAD; >>> + } >>> + >>> + return ret; >>> +} >>> + >>> +static irqreturn_t inno_hdmi_irq(int irq, void *dev_id) >>> +{ >>> + struct inno_hdmi *hdmi = dev_id; >>> + >>> + drm_helper_hpd_irq_event(hdmi->connector.dev); >>> + >>> + return IRQ_HANDLED; >>> +} >>> + >>> +static int inno_hdmi_i2c_wait(struct inno_hdmi *hdmi) >>> +{ >>> + struct inno_hdmi_i2c *i2c = hdmi->i2c; >>> + int stat; >>> + >>> + stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); >>> + if (!stat) { >>> + stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); >>> + if (!stat) >>> + return -EAGAIN; >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct >>> i2c_msg *msgs) >>> +{ >>> + int length = msgs->len; >>> + u8 *buf = msgs->buf; >>> + int ret; >>> + >>> + ret = inno_hdmi_i2c_wait(hdmi); >>> + if (ret) >>> + return ret; >>> + >>> + while (length--) >>> + *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct >>> i2c_msg *msgs) >>> +{ >>> + struct inno_hdmi_i2c *i2c = hdmi->i2c; >>> + >>> + /* >>> + * The DDC module only support read EDID message, so >>> + * we assume that each word write to this i2c adapter >>> + * should be the offset of EDID word address. >>> + */ >>> + if ((msgs->len != 1) || >>> + ((msgs->addr != DDC_ADDR) && (msgs->addr != >>> DDC_SEGMENT_ADDR))) >>> + return -EINVAL; >>> + >>> + reinit_completion(&i2c->cmp); >>> + >>> + if (msgs->addr == DDC_SEGMENT_ADDR) >>> + hdmi->i2c->segment_addr = msgs->buf[0]; >>> + if (msgs->addr == DDC_ADDR) >>> + hdmi->i2c->ddc_addr = msgs->buf[0]; >>> + >>> + /* Set edid fifo first addr */ >>> + hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00); >>> + >>> + /* Set edid word address 0x00/0x80 */ >>> + hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr); >>> + >>> + /* Set edid segment pointer */ >>> + hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, >>> hdmi->i2c->segment_addr); >>> + >>> + return 0; >>> +} >>> + >>> +static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap, >>> + struct i2c_msg *msgs, int num) >>> +{ >>> + struct inno_hdmi *hdmi = i2c_get_adapdata(adap); >>> + struct inno_hdmi_i2c *i2c = hdmi->i2c; >>> + int i, ret = 0; >>> + >>> + mutex_lock(&i2c->lock); >>> + >>> + /* Clear the EDID interrupt flag and unmute the interrupt */ >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY); >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); >>> + >>> + for (i = 0; i < num; i++) { >>> + dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", >>> + i + 1, num, msgs[i].len, msgs[i].flags); >>> + >>> + if (msgs[i].flags & I2C_M_RD) >>> + ret = inno_hdmi_i2c_read(hdmi, &msgs[i]); >>> + else >>> + ret = inno_hdmi_i2c_write(hdmi, &msgs[i]); >>> + >>> + if (ret < 0) >>> + break; >>> + } >>> + >>> + if (!ret) >>> + ret = num; >>> + >>> + /* Mute HDMI EDID interrupt */ >>> + hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); >>> + >>> + mutex_unlock(&i2c->lock); >>> + >>> + return ret; >>> +} >>> + >>> +static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter) >>> +{ >>> + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; >>> +} >>> + >>> +static const struct i2c_algorithm inno_hdmi_algorithm = { >>> + .master_xfer = inno_hdmi_i2c_xfer, >>> + .functionality = inno_hdmi_i2c_func, >>> +}; >>> + >>> +static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi >>> *hdmi) >>> +{ >>> + struct i2c_adapter *adap; >>> + struct inno_hdmi_i2c *i2c; >>> + int ret; >>> + >>> + i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); >>> + if (!i2c) >>> + return ERR_PTR(-ENOMEM); >>> + >>> + mutex_init(&i2c->lock); >>> + init_completion(&i2c->cmp); >>> + >>> + adap = &i2c->adap; >>> + adap->class = I2C_CLASS_DDC; >>> + adap->owner = THIS_MODULE; >>> + adap->dev.parent = hdmi->dev; >>> + adap->dev.of_node = hdmi->dev->of_node; >>> + adap->algo = &inno_hdmi_algorithm; >>> + strlcpy(adap->name, "Inno HDMI", sizeof(adap->name)); >>> + i2c_set_adapdata(adap, hdmi); >>> + >>> + ret = i2c_add_adapter(adap); >>> + if (ret) { >>> + dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", >>> adap->name); >>> + devm_kfree(hdmi->dev, i2c); >>> + return ERR_PTR(ret); >>> + } >>> + >>> + hdmi->i2c = i2c; >>> + >>> + dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); >>> + >>> + return adap; >>> +} >>> + >>> +static int inno_hdmi_bind(struct device *dev, struct device *master, >>> + void *data) >>> +{ >>> + struct platform_device *pdev = to_platform_device(dev); >>> + struct drm_device *drm = data; >>> + struct inno_hdmi *hdmi; >>> + struct resource *iores; >>> + int irq; >>> + int ret; >>> + >>> + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); >>> + if (!hdmi) >>> + return -ENOMEM; >>> + >>> + hdmi->dev = dev; >>> + hdmi->drm_dev = drm; >>> + >>> + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); >>> + if (!iores) >>> + return -ENXIO; >>> + >>> + hdmi->regs = devm_ioremap_resource(dev, iores); >>> + if (IS_ERR(hdmi->regs)) >>> + return PTR_ERR(hdmi->regs); >>> + >>> + hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); >>> + if (IS_ERR(hdmi->pclk)) { >>> + dev_err(hdmi->dev, "Unable to get HDMI pclk clk\n"); >>> + return PTR_ERR(hdmi->pclk); >>> + } >>> + >>> + ret = clk_prepare_enable(hdmi->pclk); >>> + if (ret) { >>> + dev_err(hdmi->dev, "Cannot enable HDMI pclk clock: %d\n", >>> ret); >>> + return ret; >>> + } >>> + >>> + irq = platform_get_irq(pdev, 0); >>> + if (irq < 0) >>> + return irq; >>> + >>> + inno_hdmi_reset(hdmi); >>> + >>> + hdmi->ddc = inno_hdmi_i2c_adapter(hdmi); >>> + if (IS_ERR(hdmi->ddc)) { >>> + hdmi->ddc = NULL; >>> + return PTR_ERR(hdmi->ddc); >>> + } >>> + >>> + /* >>> + * When IP controller haven't configured to an accurate video >>> + * timing, then the TMDS clock source would be switched to >>> + * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate, >>> + * and reconfigure the DDC clock. >>> + */ >>> + hdmi->tmds_rate = clk_get_rate(hdmi->pclk); >>> + inno_hdmi_i2c_init(hdmi); >>> + >>> + ret = inno_hdmi_register(drm, hdmi); >>> + if (ret) >>> + return ret; >>> + >>> + dev_set_drvdata(dev, hdmi); >>> + >>> + /* Unmute hotplug interrupt */ >>> + hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, >>> v_MASK_INT_HOTPLUG(1)); >>> + >>> + ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq, >>> + inno_hdmi_irq, IRQF_SHARED, >>> + dev_name(dev), hdmi); >>> + >>> + return ret; >>> +} >>> + >>> +static void inno_hdmi_unbind(struct device *dev, struct device >>> *master, >>> + void *data) >>> +{ >>> + struct inno_hdmi *hdmi = dev_get_drvdata(dev); >>> + >>> + hdmi->connector.funcs->destroy(&hdmi->connector); >>> + hdmi->encoder.funcs->destroy(&hdmi->encoder); >>> + >>> + clk_disable_unprepare(hdmi->pclk); >>> + i2c_put_adapter(hdmi->ddc); >>> +} >>> + >>> +static const struct component_ops inno_hdmi_ops = { >>> + .bind = inno_hdmi_bind, >>> + .unbind = inno_hdmi_unbind, >>> +}; >>> + >>> +static int inno_hdmi_probe(struct platform_device *pdev) >>> +{ >>> + return component_add(&pdev->dev, &inno_hdmi_ops); >>> +} >>> + >>> +static int inno_hdmi_remove(struct platform_device *pdev) >>> +{ >>> + component_del(&pdev->dev, &inno_hdmi_ops); >>> + >>> + return 0; >>> +} >>> + >>> +static const struct of_device_id inno_hdmi_dt_ids[] = { >>> + { .compatible = "rockchip,rk3036-inno-hdmi", >>> + }, >>> + {}, >>> +}; >>> +MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids); >>> + >>> +static struct platform_driver inno_hdmi_driver = { >>> + .probe = inno_hdmi_probe, >>> + .remove = inno_hdmi_remove, >>> + .driver = { >>> + .name = "innohdmi-rockchip", >>> + .of_match_table = inno_hdmi_dt_ids, >>> + }, >>> +}; >>> + >>> +module_platform_driver(inno_hdmi_driver); >>> + >>> +MODULE_AUTHOR("Zheng Yang "); >>> +MODULE_AUTHOR("Yakir Yang "); >>> +MODULE_DESCRIPTION("Rockchip Specific INNO-HDMI Driver"); >>> +MODULE_LICENSE("GPL"); >>> +MODULE_ALIAS("platform:innohdmi-rockchip"); >>> diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.h >>> b/drivers/gpu/drm/rockchip/inno_hdmi.h >>> new file mode 100644 >>> index 0000000..4ff17ad >>> --- /dev/null >>> +++ b/drivers/gpu/drm/rockchip/inno_hdmi.h >>> @@ -0,0 +1,364 @@ >>> +/* >>> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd >>> + * Zheng Yang >>> + * Yakir Yang >>> + * >>> + * This software is licensed under the terms of the GNU General Public >>> + * License version 2, as published by the Free Software Foundation, >>> and >>> + * may be copied, distributed, and modified under those terms. >>> + * >>> + * This program is distributed in the hope that it will be useful, >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >>> + * GNU General Public License for more details. >>> + */ >>> + >>> +#ifndef __INNO_HDMI_H__ >>> +#define __INNO_HDMI_H__ >>> + >>> +#define DDC_SEGMENT_ADDR 0x30 >>> + >>> +enum PWR_MODE { >>> + NORMAL, >>> + LOWER_PWR, >>> +}; >>> + >>> +#define HDMI_SCL_RATE (100*1000) >>> +#define DDC_BUS_FREQ_L 0x4b >>> +#define DDC_BUS_FREQ_H 0x4c >>> + >>> +#define HDMI_SYS_CTRL 0x00 >>> +#define m_RST_ANALOG (1 << 6) >>> +#define v_RST_ANALOG (0 << 6) >>> +#define v_NOT_RST_ANALOG (1 << 6) >>> +#define m_RST_DIGITAL (1 << 5) >>> +#define v_RST_DIGITAL (0 << 5) >>> +#define v_NOT_RST_DIGITAL (1 << 5) >>> +#define m_REG_CLK_INV (1 << 4) >>> +#define v_REG_CLK_NOT_INV (0 << 4) >>> +#define v_REG_CLK_INV (1 << 4) >>> +#define m_VCLK_INV (1 << 3) >>> +#define v_VCLK_NOT_INV (0 << 3) >>> +#define v_VCLK_INV (1 << 3) >>> +#define m_REG_CLK_SOURCE (1 << 2) >>> +#define v_REG_CLK_SOURCE_TMDS (0 << 2) >>> +#define v_REG_CLK_SOURCE_SYS (1 << 2) >>> +#define m_POWER (1 << 1) >>> +#define v_PWR_ON (0 << 1) >>> +#define v_PWR_OFF (1 << 1) >>> +#define m_INT_POL (1 << 0) >>> +#define v_INT_POL_HIGH 1 >>> +#define v_INT_POL_LOW 0 >>> + >>> +#define HDMI_VIDEO_CONTRL1 0x01 >>> +#define m_VIDEO_INPUT_FORMAT (7 << 1) >>> +#define m_DE_SOURCE (1 << 0) >>> +#define v_VIDEO_INPUT_FORMAT(n) (n << 1) >>> +#define v_DE_EXTERNAL 1 >>> +#define v_DE_INTERNAL 0 >>> +enum { >>> + VIDEO_INPUT_SDR_RGB444 = 0, >>> + VIDEO_INPUT_DDR_RGB444 = 5, >>> + VIDEO_INPUT_DDR_YCBCR422 = 6 >>> +}; >>> + >>> +#define HDMI_VIDEO_CONTRL2 0x02 >>> +#define m_VIDEO_OUTPUT_COLOR (3 << 6) >>> +#define m_VIDEO_INPUT_BITS (3 << 4) >>> +#define m_VIDEO_INPUT_CSP (1 << 0) >>> +#define v_VIDEO_OUTPUT_COLOR(n) (((n) & 0x3) << 6) >>> +#define v_VIDEO_INPUT_BITS(n) (n << 4) >>> +#define v_VIDEO_INPUT_CSP(n) (n << 0) >>> +enum { >>> + VIDEO_INPUT_12BITS = 0, >>> + VIDEO_INPUT_10BITS = 1, >>> + VIDEO_INPUT_REVERT = 2, >>> + VIDEO_INPUT_8BITS = 3, >>> +}; >>> + >>> +#define HDMI_VIDEO_CONTRL 0x03 >>> +#define m_VIDEO_AUTO_CSC (1 << 7) >>> +#define v_VIDEO_AUTO_CSC(n) (n << 7) >>> +#define m_VIDEO_C0_C2_SWAP (1 << 0) >>> +#define v_VIDEO_C0_C2_SWAP(n) (n << 0) >>> +enum { >>> + C0_C2_CHANGE_ENABLE = 0, >>> + C0_C2_CHANGE_DISABLE = 1, >>> + AUTO_CSC_DISABLE = 0, >>> + AUTO_CSC_ENABLE = 1, >>> +}; >>> + >>> +#define HDMI_VIDEO_CONTRL3 0x04 >>> +#define m_COLOR_DEPTH_NOT_INDICATED (1 << 4) >>> +#define m_SOF (1 << 3) >>> +#define m_COLOR_RANGE (1 << 2) >>> +#define m_CSC (1 << 0) >>> +#define v_COLOR_DEPTH_NOT_INDICATED(n) ((n) << 4) >>> +#define v_SOF_ENABLE (0 << 3) >>> +#define v_SOF_DISABLE (1 << 3) >>> +#define v_COLOR_RANGE_FULL (1 << 2) >>> +#define v_COLOR_RANGE_LIMITED (0 << 2) >>> +#define v_CSC_ENABLE 1 >>> +#define v_CSC_DISABLE 0 >>> + >>> +#define HDMI_AV_MUTE 0x05 >>> +#define m_AVMUTE_CLEAR (1 << 7) >>> +#define m_AVMUTE_ENABLE (1 << 6) >>> +#define m_AUDIO_MUTE (1 << 1) >>> +#define m_VIDEO_BLACK (1 << 0) >>> +#define v_AVMUTE_CLEAR(n) (n << 7) >>> +#define v_AVMUTE_ENABLE(n) (n << 6) >>> +#define v_AUDIO_MUTE(n) (n << 1) >>> +#define v_VIDEO_MUTE(n) (n << 0) >>> + >>> +#define HDMI_VIDEO_TIMING_CTL 0x08 >>> +#define v_HSYNC_POLARITY(n) (n << 3) >>> +#define v_VSYNC_POLARITY(n) (n << 2) >>> +#define v_INETLACE(n) (n << 1) >>> +#define v_EXTERANL_VIDEO(n) (n << 0) >>> + >>> +#define HDMI_VIDEO_EXT_HTOTAL_L 0x09 >>> +#define HDMI_VIDEO_EXT_HTOTAL_H 0x0a >>> +#define HDMI_VIDEO_EXT_HBLANK_L 0x0b >>> +#define HDMI_VIDEO_EXT_HBLANK_H 0x0c >>> +#define HDMI_VIDEO_EXT_HDELAY_L 0x0d >>> +#define HDMI_VIDEO_EXT_HDELAY_H 0x0e >>> +#define HDMI_VIDEO_EXT_HDURATION_L 0x0f >>> +#define HDMI_VIDEO_EXT_HDURATION_H 0x10 >>> +#define HDMI_VIDEO_EXT_VTOTAL_L 0x11 >>> +#define HDMI_VIDEO_EXT_VTOTAL_H 0x12 >>> +#define HDMI_VIDEO_EXT_VBLANK 0x13 >>> +#define HDMI_VIDEO_EXT_VDELAY 0x14 >>> +#define HDMI_VIDEO_EXT_VDURATION 0x15 >>> + >>> +#define HDMI_VIDEO_CSC_COEF 0x18 >>> + >>> +#define HDMI_AUDIO_CTRL1 0x35 >>> +enum { >>> + CTS_SOURCE_INTERNAL = 0, >>> + CTS_SOURCE_EXTERNAL = 1, >>> +}; >>> +#define v_CTS_SOURCE(n) (n << 7) >>> + >>> +enum { >>> + DOWNSAMPLE_DISABLE = 0, >>> + DOWNSAMPLE_1_2 = 1, >>> + DOWNSAMPLE_1_4 = 2, >>> +}; >>> +#define v_DOWN_SAMPLE(n) (n << 5) >>> + >>> +enum { >>> + AUDIO_SOURCE_IIS = 0, >>> + AUDIO_SOURCE_SPDIF = 1, >>> +}; >>> +#define v_AUDIO_SOURCE(n) (n << 3) >>> + >>> +#define v_MCLK_ENABLE(n) (n << 2) >>> +enum { >>> + MCLK_128FS = 0, >>> + MCLK_256FS = 1, >>> + MCLK_384FS = 2, >>> + MCLK_512FS = 3, >>> +}; >>> +#define v_MCLK_RATIO(n) (n) >>> + >>> +#define AUDIO_SAMPLE_RATE 0x37 >>> +enum { >>> + AUDIO_32K = 0x3, >>> + AUDIO_441K = 0x0, >>> + AUDIO_48K = 0x2, >>> + AUDIO_882K = 0x8, >>> + AUDIO_96K = 0xa, >>> + AUDIO_1764K = 0xc, >>> + AUDIO_192K = 0xe, >>> +}; >>> + >>> +#define AUDIO_I2S_MODE 0x38 >>> +enum { >>> + I2S_CHANNEL_1_2 = 1, >>> + I2S_CHANNEL_3_4 = 3, >>> + I2S_CHANNEL_5_6 = 7, >>> + I2S_CHANNEL_7_8 = 0xf >>> +}; >>> +#define v_I2S_CHANNEL(n) ((n) << 2) >>> +enum { >>> + I2S_STANDARD = 0, >>> + I2S_LEFT_JUSTIFIED = 1, >>> + I2S_RIGHT_JUSTIFIED = 2, >>> +}; >>> +#define v_I2S_MODE(n) (n) >>> + >>> +#define AUDIO_I2S_MAP 0x39 >>> +#define AUDIO_I2S_SWAPS_SPDIF 0x3a >>> +#define v_SPIDF_FREQ(n) (n) >>> + >>> +#define N_32K 0x1000 >>> +#define N_441K 0x1880 >>> +#define N_882K 0x3100 >>> +#define N_1764K 0x6200 >>> +#define N_48K 0x1800 >>> +#define N_96K 0x3000 >>> +#define N_192K 0x6000 >>> + >>> +#define HDMI_AUDIO_CHANNEL_STATUS 0x3e >>> +#define m_AUDIO_STATUS_NLPCM (1 << 7) >>> +#define m_AUDIO_STATUS_USE (1 << 6) >>> +#define m_AUDIO_STATUS_COPYRIGHT (1 << 5) >>> +#define m_AUDIO_STATUS_ADDITION (3 << 2) >>> +#define m_AUDIO_STATUS_CLK_ACCURACY (2 << 0) >>> +#define v_AUDIO_STATUS_NLPCM(n) ((n & 1) << 7) >>> +#define AUDIO_N_H 0x3f >>> +#define AUDIO_N_M 0x40 >>> +#define AUDIO_N_L 0x41 >>> + >>> +#define HDMI_AUDIO_CTS_H 0x45 >>> +#define HDMI_AUDIO_CTS_M 0x46 >>> +#define HDMI_AUDIO_CTS_L 0x47 >>> + >>> +#define HDMI_DDC_CLK_L 0x4b >>> +#define HDMI_DDC_CLK_H 0x4c >>> + >>> +#define HDMI_EDID_SEGMENT_POINTER 0x4d >>> +#define HDMI_EDID_WORD_ADDR 0x4e >>> +#define HDMI_EDID_FIFO_OFFSET 0x4f >>> +#define HDMI_EDID_FIFO_ADDR 0x50 >>> + >>> +#define HDMI_PACKET_SEND_MANUAL 0x9c >>> +#define HDMI_PACKET_SEND_AUTO 0x9d >>> +#define m_PACKET_GCP_EN (1 << 7) >>> +#define m_PACKET_MSI_EN (1 << 6) >>> +#define m_PACKET_SDI_EN (1 << 5) >>> +#define m_PACKET_VSI_EN (1 << 4) >>> +#define v_PACKET_GCP_EN(n) ((n & 1) << 7) >>> +#define v_PACKET_MSI_EN(n) ((n & 1) << 6) >>> +#define v_PACKET_SDI_EN(n) ((n & 1) << 5) >>> +#define v_PACKET_VSI_EN(n) ((n & 1) << 4) >>> + >>> +#define HDMI_CONTROL_PACKET_BUF_INDEX 0x9f >>> +enum { >>> + INFOFRAME_VSI = 0x05, >>> + INFOFRAME_AVI = 0x06, >>> + INFOFRAME_AAI = 0x08, >>> +}; >>> + >>> +#define HDMI_CONTROL_PACKET_ADDR 0xa0 >>> +#define HDMI_SIZE_VSI_INFOFRAME 0x0A >>> +#define HDMI_SIZE_AVI_INFOFRAME 0x11 >>> +#define HDMI_SIZE_AUDIO_INFOFRAME 0x0F >>> +enum { >>> + AVI_COLOR_MODE_RGB = 0, >>> + AVI_COLOR_MODE_YCBCR422 = 1, >>> + AVI_COLOR_MODE_YCBCR444 = 2, >>> + AVI_COLORIMETRY_NO_DATA = 0, >>> + >>> + AVI_COLORIMETRY_SMPTE_170M = 1, >>> + AVI_COLORIMETRY_ITU709 = 2, >>> + AVI_COLORIMETRY_EXTENDED = 3, >>> + >>> + AVI_CODED_FRAME_ASPECT_NO_DATA = 0, >>> + AVI_CODED_FRAME_ASPECT_4_3 = 1, >>> + AVI_CODED_FRAME_ASPECT_16_9 = 2, >>> + >>> + ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, >>> + ACTIVE_ASPECT_RATE_4_3 = 0x09, >>> + ACTIVE_ASPECT_RATE_16_9 = 0x0A, >>> + ACTIVE_ASPECT_RATE_14_9 = 0x0B, >>> +}; >>> + >>> +#define HDMI_HDCP_CTRL 0x52 >>> +#define m_HDMI_DVI (1 << 1) >>> +#define v_HDMI_DVI(n) (n << 1) >>> + >>> +#define HDMI_INTERRUPT_MASK1 0xc0 >>> +#define HDMI_INTERRUPT_STATUS1 0xc1 >>> +#define m_INT_ACTIVE_VSYNC (1 << 5) >>> +#define m_INT_EDID_READY (1 << 2) >>> + >>> +#define HDMI_INTERRUPT_MASK2 0xc2 >>> +#define HDMI_INTERRUPT_STATUS2 0xc3 >>> +#define m_INT_HDCP_ERR (1 << 7) >>> +#define m_INT_BKSV_FLAG (1 << 6) >>> +#define m_INT_HDCP_OK (1 << 4) >>> + >>> +#define HDMI_STATUS 0xc8 >>> +#define m_HOTPLUG (1 << 7) >>> +#define m_MASK_INT_HOTPLUG (1 << 5) >>> +#define m_INT_HOTPLUG (1 << 1) >>> +#define v_MASK_INT_HOTPLUG(n) ((n & 0x1) << 5) >>> + >>> +#define HDMI_COLORBAR 0xc9 >>> + >>> +#define HDMI_PHY_SYNC 0xce >>> +#define HDMI_PHY_SYS_CTL 0xe0 >>> +#define m_TMDS_CLK_SOURCE (1 << 5) >>> +#define v_TMDS_FROM_PLL (0 << 5) >>> +#define v_TMDS_FROM_GEN (1 << 5) >>> +#define m_PHASE_CLK (1 << 4) >>> +#define v_DEFAULT_PHASE (0 << 4) >>> +#define v_SYNC_PHASE (1 << 4) >>> +#define m_TMDS_CURRENT_PWR (1 << 3) >>> +#define v_TURN_ON_CURRENT (0 << 3) >>> +#define v_CAT_OFF_CURRENT (1 << 3) >>> +#define m_BANDGAP_PWR (1 << 2) >>> +#define v_BANDGAP_PWR_UP (0 << 2) >>> +#define v_BANDGAP_PWR_DOWN (1 << 2) >>> +#define m_PLL_PWR (1 << 1) >>> +#define v_PLL_PWR_UP (0 << 1) >>> +#define v_PLL_PWR_DOWN (1 << 1) >>> +#define m_TMDS_CHG_PWR (1 << 0) >>> +#define v_TMDS_CHG_PWR_UP (0 << 0) >>> +#define v_TMDS_CHG_PWR_DOWN (1 << 0) >>> + >>> +#define HDMI_PHY_CHG_PWR 0xe1 >>> +#define v_CLK_CHG_PWR(n) ((n & 1) << 3) >>> +#define v_DATA_CHG_PWR(n) ((n & 7) << 0) >>> + >>> +#define HDMI_PHY_DRIVER 0xe2 >>> +#define v_CLK_MAIN_DRIVER(n) (n << 4) >>> +#define v_DATA_MAIN_DRIVER(n) (n << 0) >>> + >>> +#define HDMI_PHY_PRE_EMPHASIS 0xe3 >>> +#define v_PRE_EMPHASIS(n) ((n & 7) << 4) >>> +#define v_CLK_PRE_DRIVER(n) ((n & 3) << 2) >>> +#define v_DATA_PRE_DRIVER(n) ((n & 3) << 0) >>> + >>> +#define HDMI_PHY_FEEDBACK_DIV_RATIO_LOW 0xe7 >>> +#define v_FEEDBACK_DIV_LOW(n) (n & 0xff) >>> +#define HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH 0xe8 >>> +#define v_FEEDBACK_DIV_HIGH(n) (n & 1) >>> + >>> +#define HDMI_PHY_PRE_DIV_RATIO 0xed >>> +#define v_PRE_DIV_RATIO(n) (n & 0x1f) >>> + >>> +#define HDMI_CEC_CTRL 0xd0 >>> +#define m_ADJUST_FOR_HISENSE (1 << 6) >>> +#define m_REJECT_RX_BROADCAST (1 << 5) >>> +#define m_BUSFREETIME_ENABLE (1 << 2) >>> +#define m_REJECT_RX (1 << 1) >>> +#define m_START_TX (1 << 0) >>> + >>> +#define HDMI_CEC_DATA 0xd1 >>> +#define HDMI_CEC_TX_OFFSET 0xd2 >>> +#define HDMI_CEC_RX_OFFSET 0xd3 >>> +#define HDMI_CEC_CLK_H 0xd4 >>> +#define HDMI_CEC_CLK_L 0xd5 >>> +#define HDMI_CEC_TX_LENGTH 0xd6 >>> +#define HDMI_CEC_RX_LENGTH 0xd7 >>> +#define HDMI_CEC_TX_INT_MASK 0xd8 >>> +#define m_TX_DONE (1 << 3) >>> +#define m_TX_NOACK (1 << 2) >>> +#define m_TX_BROADCAST_REJ (1 << 1) >>> +#define m_TX_BUSNOTFREE (1 << 0) >>> + >>> +#define HDMI_CEC_RX_INT_MASK 0xd9 >>> +#define m_RX_LA_ERR (1 << 4) >>> +#define m_RX_GLITCH (1 << 3) >>> +#define m_RX_DONE (1 << 0) >>> + >>> +#define HDMI_CEC_TX_INT 0xda >>> +#define HDMI_CEC_RX_INT 0xdb >>> +#define HDMI_CEC_BUSFREETIME_L 0xdc >>> +#define HDMI_CEC_BUSFREETIME_H 0xdd >>> +#define HDMI_CEC_LOGICADDR 0xde >>> + >>> +#endif /* __INNO_HDMI_H__ */ >> >> > >