From mboxrd@z Thu Jan 1 00:00:00 1970 From: Caesar Wang Subject: Re: [PATCH v3 1/2] drm: rockchip/hdmi: add Innosilicon HDMI support Date: Sun, 24 Jan 2016 15:34:07 +0800 Message-ID: <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> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <569C3E36.10103-TNX95d0MmH7DzftRWevZcw@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+glpar-linux-rockchip=m.gmane.org-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org To: Yakir Yang Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Heiko Stuebner , David Airlie , linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org, linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, Rob Herring , Thierry Reding , linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, Mark yao List-Id: linux-rockchip.vger.kernel.org SGkKCuWcqCAyMDE25bm0MDHmnIgxOOaXpSAwOToyMSwgTWFyayB5YW8g5YaZ6YGTOgo+IEhpIFlh a2lyCj4KPiBJJ2QgbGlrZSB5b3UgY2FuIGNoYW5nZSB5b3VyIHBhdGNoIHRpdGxlIGludG8gImRy bS9yb2NrY2hpcC9oZG1pIiwgc28gCj4gd2hlbiBJIHNlYXJjaCBwYXRjaGVzIHVzZSAiZHJtL3Jv Y2tjaGlwIiBjYW4gZmluZCB5b3VyIHBhdGNoLgo+Cj4gYW5kIEkgaGF2ZSBzb21lIGFkdmljZXMg bWFpbCBpbmxpbmUuCj4KPiBUaGFua3M6LSkKPgo+IE9uIDIwMTblubQwMeaciDE15pelIDE3OjM4 LCBZYWtpciBZYW5nIHdyb3RlOgo+PiBUaGUgSW5ub3NpbGljb24gSERNSSBpcyBhIGxvdyBwb3dl ciBIRE1JIDEuNCB0cmFuc21pdHRlcgo+PiBJUCwgYW5kIGl0IGhhdmUgYmVlbiBpbnRlZ3JhdGVk IG9uIHNvbWUgcm9ja2NoaXAgQ1BVcwo+PiAobGlrZSBSSzMwMzYsIFJLMzEyeCkuCj4+Cj4+IFNp Z25lZC1vZmYtYnk6IFlha2lyIFlhbmcgPHlra0Byb2NrLWNoaXBzLmNvbT4KPj4gLS0tCj4+IENo YW5nZXMgaW4gdjM6Cj4+IC0gVXNlIGVuY29kZXIgZW5hYmxlL2Rpc2FibGUgZnVuY3Rpb24sIGFu ZCByZW1vdmUgdGhlIGVuY29kZXIgRFBNUyAKPj4gZnVuY3Rpb24KPj4gLSBLZWVwIEhETUkgUExM IHBvd2VyIG9uIGluIHN0YW5kYnkgbW9kZQo+Pgo+PiBDaGFuZ2VzIGluIHYyOgo+PiAtIFVzaW5n IERSTSBhdG9taWMgaGVscGVyIGZ1bmN0aW9ucyBmb3IgY29ubmVjdG9yIGluaXQgKE1hcmspCj4+ IC0gUmVtb3ZlICJoZG1pLT5jb25uZWN0b3IuZW5jb2RlciA9IGVuY29kZXI7IiAoTWFyaykKPj4K Pj4gICBkcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvS2NvbmZpZyAgICAgfCAgIDggKwo+PiAgIGRy aXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9NYWtlZmlsZSAgICB8ICAgMSArCj4+ICAgZHJpdmVycy9n cHUvZHJtL3JvY2tjaGlwL2lubm9faGRtaS5jIHwgOTk5IAo+PiArKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKwo+PiAgIGRyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9pbm5vX2hkbWku aCB8IDM2NCArKysrKysrKysrKysrCj4+ICAgNCBmaWxlcyBjaGFuZ2VkLCAxMzcyIGluc2VydGlv bnMoKykKPj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL2lu bm9faGRtaS5jCj4+ICAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS9yb2NrY2hp cC9pbm5vX2hkbWkuaAo+Pgo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlw L0tjb25maWcgCj4+IGIvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL0tjb25maWcKPj4gaW5kZXgg MzUyMTVmNi4uYTUwMTRlMCAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlw L0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL0tjb25maWcKPj4gQEAg LTI1LDMgKzI1LDExIEBAIGNvbmZpZyBST0NLQ0hJUF9EV19IRE1JCj4+ICAgICAgICAgZm9yIHRo ZSBTeW5vcHN5cyBEZXNpZ25XYXJlIEhETUkgZHJpdmVyLiBJZiB5b3Ugd2FudCB0bwo+PiAgICAg ICAgIGVuYWJsZSBIRE1JIG9uIFJLMzI4OCBiYXNlZCBTb0MsIHlvdSBzaG91bGQgc2VsZXQgdGhp cwo+PiAgICAgICAgIG9wdGlvbi4KPj4gKwo+PiArY29uZmlnIFJPQ0tDSElQX0lOTk9fSERNSQo+ PiArICAgIHRyaXN0YXRlICJSb2NrY2hpcCBzcGVjaWZpYyBleHRlbnNpb25zIGZvciBJbm5vc2ls aWNvbiBIRE1JIgo+PiArICAgICAgICBkZXBlbmRzIG9uIERSTV9ST0NLQ0hJUAo+PiArICAgICAg ICBoZWxwCj4+ICsgICAgICBUaGlzIHNlbGVjdHMgc3VwcG9ydCBmb3IgUm9ja2NoaXAgU29DIHNw ZWNpZmljIGV4dGVuc2lvbnMKPj4gKyAgICAgIGZvciB0aGUgSW5ub3NpbGljb24gSERNSSBkcml2 ZXIuIElmIHlvdSB3YW50IHRvIGVuYWJsZQo+PiArICAgICAgSERNSSBvbiBSSzMwMzYgYmFzZWQg U29DLCB5b3Ugc2hvdWxkIHNlbGV0IHRoaXMgb3B0aW9uLgoKVGhhdCdzIHNlZW0gaGFzIHNvbWUg Y29uZmxpY3RzIHNpbmNlIHRoZSBNSVBJIGRyaXZlciBsYW5kIGluIG1haW5saW5lLgpTbyB5b3Ug bmVlZCB1cGRhdGUgaXQgYmFzZWQgb24gdGhlIGxhc3Rlc3Qga2VybmVsLgoKPj4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9NYWtlZmlsZSAKPj4gYi9kcml2ZXJzL2dwdS9k cm0vcm9ja2NoaXAvTWFrZWZpbGUKPj4gaW5kZXggYTlkMzgwZi4uZGEyYmY3NiAxMDA2NDQKPj4g LS0tIGEvZHJpdmVycy9ncHUvZHJtL3JvY2tjaGlwL01ha2VmaWxlCj4+ICsrKyBiL2RyaXZlcnMv Z3B1L2RybS9yb2NrY2hpcC9NYWtlZmlsZQo+PiBAQCAtNiw2ICs2LDcgQEAgcm9ja2NoaXBkcm0t eSA6PSByb2NrY2hpcF9kcm1fZHJ2Lm8gcm9ja2NoaXBfZHJtX2ZiLm8gCj4+IHJvY2tjaGlwX2Ry bV9mYmRldi5vIFwKPj4gICAgICAgICAgIHJvY2tjaGlwX2RybV9nZW0ubwo+PiAgICAgb2JqLSQo Q09ORklHX1JPQ0tDSElQX0RXX0hETUkpICs9IGR3X2hkbWktcm9ja2NoaXAubwo+PiArb2JqLSQo Q09ORklHX1JPQ0tDSElQX0lOTk9fSERNSSkgKz0gaW5ub19oZG1pLm8KPj4gICAgIG9iai0kKENP TkZJR19EUk1fUk9DS0NISVApICs9IHJvY2tjaGlwZHJtLm8gcm9ja2NoaXBfZHJtX3ZvcC5vIFwK Pj4gICAgICAgICAgICAgICAgICAgcm9ja2NoaXBfdm9wX3JlZy5vCj4+IGRpZmYgLS1naXQgYS9k cml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmMgCj4+IGIvZHJpdmVycy9ncHUvZHJt L3JvY2tjaGlwL2lubm9faGRtaS5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAw MDAwMDAuLmRjOTgxNzkKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0v cm9ja2NoaXAvaW5ub19oZG1pLmMKPj4gQEAgLTAsMCArMSw5OTkgQEAKPj4gKy8qCj4+ICsgKiBD b3B5cmlnaHQgKEMpIEZ1emhvdSBSb2NrY2hpcCBFbGVjdHJvbmljcyBDby5MdGQKPj4gKyAqICAg IFpoZW5nIFlhbmcgPHpoZW5neWFuZ0Byb2NrLWNoaXBzLmNvbT4KPj4gKyAqICAgIFlha2lyIFlh bmcgPHlra0Byb2NrLWNoaXBzLmNvbT4KPj4gKyAqCj4+ICsgKiBUaGlzIHNvZnR3YXJlIGlzIGxp Y2Vuc2VkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljCj4+ICsgKiBM aWNlbnNlIHZlcnNpb24gMiwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5k YXRpb24sIGFuZAo+PiArICogbWF5IGJlIGNvcGllZCwgZGlzdHJpYnV0ZWQsIGFuZCBtb2RpZmll ZCB1bmRlciB0aG9zZSB0ZXJtcy4KPj4gKyAqCj4+ICsgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJp YnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKPj4gKyAqIGJ1dCBXSVRI T1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCj4+ ICsgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0Uu ICBTZWUgdGhlCj4+ICsgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRh aWxzLgo+PiArICovCj4+ICsKPj4gKyNpbmNsdWRlIDxsaW51eC9pcnEuaD4KPj4gKyNpbmNsdWRl IDxsaW51eC9jbGsuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgo+PiArI2luY2x1ZGUg PGxpbnV4L2Vyci5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2hkbWkuaD4KPj4gKyNpbmNsdWRlIDxs aW51eC9tZmQvc3lzY29uLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+ICsjaW5j bHVkZSA8bGludXgvbXV0ZXguaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9vZl9kZXZpY2UuaD4KPj4g Kwo+PiArI2luY2x1ZGUgPGRybS9kcm1fb2YuaD4KPj4gKyNpbmNsdWRlIDxkcm0vZHJtUC5oPgo+ PiArI2luY2x1ZGUgPGRybS9kcm1fYXRvbWljX2hlbHBlci5oPgo+PiArI2luY2x1ZGUgPGRybS9k cm1fY3J0Y19oZWxwZXIuaD4KPj4gKyNpbmNsdWRlIDxkcm0vZHJtX2VkaWQuaD4KPj4gKyNpbmNs dWRlIDxkcm0vZHJtX2VuY29kZXJfc2xhdmUuaD4KPj4gKwo+PiArI2luY2x1ZGUgInJvY2tjaGlw X2RybV9kcnYuaCIKPj4gKyNpbmNsdWRlICJyb2NrY2hpcF9kcm1fdm9wLmgiCj4+ICsKPj4gKyNp bmNsdWRlICJpbm5vX2hkbWkuaCIKPj4gKwo+PiArI2RlZmluZSB0b19pbm5vX2hkbWkoeCkgICAg Y29udGFpbmVyX29mKHgsIHN0cnVjdCBpbm5vX2hkbWksIHgpCj4+ICsKPj4gK3N0cnVjdCBoZG1p X2RhdGFfaW5mbyB7Cj4+ICsgICAgaW50IHZpYzsKPj4gKyAgICBib29sIHNpbmtfaXNfaGRtaTsK Pj4gKyAgICBib29sIHNpbmtfaGFzX2F1ZGlvOwo+PiArICAgIHVuc2lnbmVkIGludCBlbmNfaW5f Zm9ybWF0Owo+PiArICAgIHVuc2lnbmVkIGludCBlbmNfb3V0X2Zvcm1hdDsKPj4gKyAgICB1bnNp Z25lZCBpbnQgY29sb3JpbWV0cnk7Cj4+ICt9Owo+PiArCj4+ICtzdHJ1Y3QgaW5ub19oZG1pX2ky YyB7Cj4+ICsgICAgc3RydWN0IGkyY19hZGFwdGVyIGFkYXA7Cj4+ICsKPj4gKyAgICB1OCBkZGNf YWRkcjsKPj4gKyAgICB1OCBzZWdtZW50X2FkZHI7Cj4+ICsKPj4gKyAgICBzdHJ1Y3QgbXV0ZXgg bG9jazsKPj4gKyAgICBzdHJ1Y3QgY29tcGxldGlvbiBjbXA7Cj4+ICt9Owo+PiArCj4+ICtzdHJ1 Y3QgaW5ub19oZG1pIHsKPj4gKyAgICBzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4+ICsgICAgc3RydWN0 IGRybV9kZXZpY2UgKmRybV9kZXY7Cj4+ICsKPj4gKyAgICBpbnQgaXJxOwo+PiArICAgIHN0cnVj dCBjbGsgKnBjbGs7Cj4+ICsgICAgdm9pZCBfX2lvbWVtICpyZWdzOwo+PiArCj4+ICsgICAgc3Ry dWN0IGRybV9jb25uZWN0b3IgICAgY29ubmVjdG9yOwo+PiArICAgIHN0cnVjdCBkcm1fZW5jb2Rl ciAgICBlbmNvZGVyOwo+PiArCj4+ICsgICAgc3RydWN0IGlubm9faGRtaV9pMmMgKmkyYzsKPj4g KyAgICBzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmRkYzsKPj4gKwo+PiArICAgIHVuc2lnbmVkIGludCB0 bWRzX3JhdGU7Cj4+ICsKPj4gKyAgICBzdHJ1Y3QgaGRtaV9kYXRhX2luZm8gICAgaGRtaV9kYXRh Owo+PiArICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlIHByZXZpb3VzX21vZGU7Cj4+ICt9Owo+ PiArCj4+ICtlbnVtIHsKPj4gKyAgICBDU0NfSVRVNjAxXzE2XzIzNV9UT19SR0JfMF8yNTVfOEJJ VCwKPj4gKyAgICBDU0NfSVRVNjAxXzBfMjU1X1RPX1JHQl8wXzI1NV84QklULAo+PiArICAgIENT Q19JVFU3MDlfMTZfMjM1X1RPX1JHQl8wXzI1NV84QklULAo+PiArICAgIENTQ19SR0JfMF8yNTVf VE9fSVRVNjAxXzE2XzIzNV84QklULAo+PiArICAgIENTQ19SR0JfMF8yNTVfVE9fSVRVNzA5XzE2 XzIzNV84QklULAo+PiArICAgIENTQ19SR0JfMF8yNTVfVE9fUkdCXzE2XzIzNV84QklULAo+PiAr fTsKPj4gKwo+PiArc3RhdGljIGNvbnN0IGNoYXIgY29lZmZfY3NjW11bMjRdID0gewo+PiArICAg IC8qCj4+ICsgICAgICogWVVWMlJHQjo2MDEgU0QgbW9kZShZWzE2OjIzNV0sIFVWWzE2OjI0MF0s IFJHQlswOjI1NV0pOgo+PiArICAgICAqICAgUiA9IDEuMTY0KlkgKyAxLjU5NipWIC0gMjA0Cj4+ ICsgICAgICogICBHID0gMS4xNjQqWSAtIDAuMzkxKlUgLSAwLjgxMypWICsgMTU0Cj4+ICsgICAg ICogICBCID0gMS4xNjQqWSArIDIuMDE4KlUgLSAyNTgKPj4gKyAgICAgKi8KPj4gKyAgICB7Cj4+ ICsgICAgICAgIDB4MDQsIDB4YTcsIDB4MDAsIDB4MDAsIDB4MDYsIDB4NjIsIDB4MDIsIDB4Y2Ms Cj4+ICsgICAgICAgIDB4MDQsIDB4YTcsIDB4MTEsIDB4OTAsIDB4MTMsIDB4NDAsIDB4MDAsIDB4 OWEsCj4+ICsgICAgICAgIDB4MDQsIDB4YTcsIDB4MDgsIDB4MTIsIDB4MDAsIDB4MDAsIDB4MDMs IDB4MDIKPj4gKyAgICB9LAo+PiArICAgIC8qCj4+ICsgICAgICogWVVWMlJHQjo2MDEgU0QgbW9k ZShZVVZbMDoyNTVdLFJHQlswOjI1NV0pOgo+PiArICAgICAqICAgUiA9IFkgKyAxLjQwMipWIC0g MjQ4Cj4+ICsgICAgICogICBHID0gWSAtIDAuMzQ0KlUgLSAwLjcxNCpWICsgMTM1Cj4+ICsgICAg ICogICBCID0gWSArIDEuNzcyKlUgLSAyMjcKPj4gKyAgICAgKi8KPj4gKyAgICB7Cj4+ICsgICAg ICAgIDB4MDQsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDUsIDB4OWIsIDB4MDIsIDB4ZjgsCj4+ICsg ICAgICAgIDB4MDQsIDB4MDAsIDB4MTEsIDB4NjAsIDB4MTIsIDB4ZGIsIDB4MDAsIDB4ODcsCj4+ ICsgICAgICAgIDB4MDQsIDB4MDAsIDB4MDcsIDB4MTYsIDB4MDAsIDB4MDAsIDB4MDIsIDB4ZTMK Pj4gKyAgICB9LAo+PiArICAgIC8qCj4+ICsgICAgICogWVVWMlJHQjo3MDkgSEQgbW9kZShZWzE2 OjIzNV0sVVZbMTY6MjQwXSxSR0JbMDoyNTVdKToKPj4gKyAgICAgKiAgIFIgPSAxLjE2NCpZICsg MS43OTMqViAtIDI0OAo+PiArICAgICAqICAgRyA9IDEuMTY0KlkgLSAwLjIxMypVIC0gMC41MzQq ViArIDc3Cj4+ICsgICAgICogICBCID0gMS4xNjQqWSArIDIuMTE1KlUgLSAyODkKPj4gKyAgICAg Ki8KPj4gKyAgICB7Cj4+ICsgICAgICAgIDB4MDQsIDB4YTcsIDB4MDAsIDB4MDAsIDB4MDcsIDB4 MmMsIDB4MDIsIDB4ZjgsCj4+ICsgICAgICAgIDB4MDQsIDB4YTcsIDB4MTAsIDB4ZGEsIDB4MTIs IDB4MjIsIDB4MDAsIDB4NGQsCj4+ICsgICAgICAgIDB4MDQsIDB4YTcsIDB4MDgsIDB4NzQsIDB4 MDAsIDB4MDAsIDB4MDMsIDB4MjEKPj4gKyAgICB9LAo+PiArCj4+ICsgICAgLyoKPj4gKyAgICAg KiBSR0IyWVVWOjYwMSBTRCBtb2RlOgo+PiArICAgICAqICAgQ2IgPSAtMC4yOTFHIC0gMC4xNDhS ICsgMC40MzlCICsgMTI4Cj4+ICsgICAgICogICBZICA9IDAuNTA0RyAgKyAwLjI1N1IgKyAwLjA5 OEIgKyAxNgo+PiArICAgICAqICAgQ3IgPSAtMC4zNjhHICsgMC40MzlSIC0gMC4wNzFCICsgMTI4 Cj4+ICsgICAgICovCj4+ICsgICAgewo+PiArICAgICAgICAweDExLCAweDVmLCAweDAxLCAweDgy LCAweDEwLCAweDIzLCAweDAwLCAweDgwLAo+PiArICAgICAgICAweDAyLCAweDFjLCAweDAwLCAw eGExLCAweDAwLCAweDM2LCAweDAwLCAweDFlLAo+PiArICAgICAgICAweDExLCAweDI5LCAweDEw LCAweDU5LCAweDAxLCAweDgyLCAweDAwLCAweDgwCj4+ICsgICAgfSwKPj4gKyAgICAvKgo+PiAr ICAgICAqIFJHQjJZVVY6NzA5IEhEIG1vZGU6Cj4+ICsgICAgICogICBDYiA9IC0gMC4zMzhHIC0g MC4xMDFSICsgMC40MzlCICsgMTI4Cj4+ICsgICAgICogICBZICA9IDAuNjE0RyAgICsgMC4xODNS ICsgMC4wNjJCICsgMTYKPj4gKyAgICAgKiAgIENyID0gLSAwLjM5OUcgKyAwLjQzOVIgLSAwLjA0 MEIgKyAxMjgKPj4gKyAgICAgKi8KPj4gKyAgICB7Cj4+ICsgICAgICAgIDB4MTEsIDB4OTgsIDB4 MDEsIDB4YzEsIDB4MTAsIDB4MjgsIDB4MDAsIDB4ODAsCj4+ICsgICAgICAgIDB4MDIsIDB4NzQs IDB4MDAsIDB4YmIsIDB4MDAsIDB4M2YsIDB4MDAsIDB4MTAsCj4+ICsgICAgICAgIDB4MTEsIDB4 NWEsIDB4MTAsIDB4NjcsIDB4MDEsIDB4YzEsIDB4MDAsIDB4ODAKPj4gKyAgICB9LAo+PiArICAg IC8qCj4+ICsgICAgICogUkdCWzA6MjU1XTJSR0JbMTY6MjM1XToKPj4gKyAgICAgKiAgIFInID0g UiB4ICgyMzUtMTYpLzI1NSArIDE2Owo+PiArICAgICAqICAgRycgPSBHIHggKDIzNS0xNikvMjU1 ICsgMTY7Cj4+ICsgICAgICogICBCJyA9IEIgeCAoMjM1LTE2KS8yNTUgKyAxNjsKPj4gKyAgICAg Ki8KPj4gKyAgICB7Cj4+ICsgICAgICAgIDB4MDAsIDB4MDAsIDB4MDMsIDB4NkYsIDB4MDAsIDB4 MDAsIDB4MDAsIDB4MTAsCj4+ICsgICAgICAgIDB4MDMsIDB4NkYsIDB4MDAsIDB4MDAsIDB4MDAs IDB4MDAsIDB4MDAsIDB4MTAsCj4+ICsgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4 MDMsIDB4NkYsIDB4MDAsIDB4MTAKPj4gKyAgICB9LAo+PiArfTsKPj4gKwo+PiArc3RhdGljIGlu bGluZSB1OCBoZG1pX3JlYWRiKHN0cnVjdCBpbm5vX2hkbWkgKmhkbWksIHUxNiBvZmZzZXQpCj4+ ICt7Cj4+ICsgICAgcmV0dXJuIHJlYWRsX3JlbGF4ZWQoaGRtaS0+cmVncyArIChvZmZzZXQpICog MHgwNCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbmxpbmUgdm9pZCBoZG1pX3dyaXRlYihzdHJ1 Y3QgaW5ub19oZG1pICpoZG1pLCB1MTYgb2Zmc2V0LCAKPj4gdTMyIHZhbCkKPj4gK3sKPj4gKyAg ICB3cml0ZWxfcmVsYXhlZCh2YWwsIGhkbWktPnJlZ3MgKyAob2Zmc2V0KSAqIDB4MDQpOwo+PiAr fQo+PiArCj4+ICtzdGF0aWMgaW5saW5lIHZvaWQgaGRtaV9tb2RiKHN0cnVjdCBpbm5vX2hkbWkg KmhkbWksIHUxNiBvZmZzZXQsCj4+ICsgICAgICAgICAgICAgICAgIHUzMiBtc2ssIHUzMiB2YWwp Cj4+ICt7Cj4+ICsgICAgdTggdGVtcCA9IGhkbWlfcmVhZGIoaGRtaSwgb2Zmc2V0KSAmIH5tc2s7 Cj4+ICsKPj4gKyAgICB0ZW1wIHw9IHZhbCAmIG1zazsKPj4gKyAgICBoZG1pX3dyaXRlYihoZG1p LCBvZmZzZXQsIHRlbXApOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBpbm5vX2hkbWlfaTJj X2luaXQoc3RydWN0IGlubm9faGRtaSAqaGRtaSkKPj4gK3sKPj4gKyAgICBpbnQgZGRjX2J1c19m cmVxOwo+PiArCj4+ICsgICAgZGRjX2J1c19mcmVxID0gKGhkbWktPnRtZHNfcmF0ZSA+PiAyKSAv IEhETUlfU0NMX1JBVEU7Cj4+ICsKPj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBERENfQlVTX0ZS RVFfTCwgZGRjX2J1c19mcmVxICYgMHhGRik7Cj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgRERD X0JVU19GUkVRX0gsIChkZGNfYnVzX2ZyZXEgPj4gOCkgJiAweEZGKTsKPj4gKwo+PiArICAgIC8q IENsZWFyIHRoZSBFRElEIGludGVycnVwdCBmbGFnIGFuZCBtdXRlIHRoZSBpbnRlcnJ1cHQgKi8K Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX0lOVEVSUlVQVF9NQVNLMSwgMCk7Cj4+ICsg ICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9JTlRFUlJVUFRfU1RBVFVTMSwgbV9JTlRfRURJRF9S RUFEWSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGlubm9faGRtaV9zeXNfcG93ZXIoc3Ry dWN0IGlubm9faGRtaSAqaGRtaSwgYm9vbCBlbmFibGUpCj4+ICt7Cj4+ICsgICAgaWYgKGVuYWJs ZSkKPj4gKyAgICAgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfU1lTX0NUUkwsIG1fUE9XRVIsIHZf UFdSX09OKTsKPj4gKyAgICBlbHNlCj4+ICsgICAgICAgIGhkbWlfbW9kYihoZG1pLCBIRE1JX1NZ U19DVFJMLCBtX1BPV0VSLCB2X1BXUl9PRkYpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBp bm5vX2hkbWlfc2V0X3B3cl9tb2RlKHN0cnVjdCBpbm5vX2hkbWkgKmhkbWksIGludCBtb2RlKQo+ PiArewo+PiArICAgIHN3aXRjaCAobW9kZSkgewo+PiArICAgIGNhc2UgTk9STUFMOgo+PiArICAg ICAgICBpbm5vX2hkbWlfc3lzX3Bvd2VyKGhkbWksIGZhbHNlKTsKPj4gKwo+PiArICAgICAgICBo ZG1pX3dyaXRlYihoZG1pLCBIRE1JX1BIWV9QUkVfRU1QSEFTSVMsIDB4NmYpOwo+PiArICAgICAg ICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1BIWV9EUklWRVIsIDB4YmIpOwo+PiArCj4+ICsgICAg ICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfUEhZX1NZU19DVEwsIDB4MTUpOwo+PiArICAgICAg ICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1BIWV9TWVNfQ1RMLCAweDE0KTsKPj4gKyAgICAgICAg aGRtaV93cml0ZWIoaGRtaSwgSERNSV9QSFlfU1lTX0NUTCwgMHgxMCk7Cj4+ICsgICAgICAgIGhk bWlfd3JpdGViKGhkbWksIEhETUlfUEhZX0NIR19QV1IsIDB4MGYpOwo+PiArICAgICAgICBoZG1p X3dyaXRlYihoZG1pLCBIRE1JX1BIWV9TWU5DLCAweDAwKTsKPj4gKyAgICAgICAgaGRtaV93cml0 ZWIoaGRtaSwgSERNSV9QSFlfU1lOQywgMHgwMSk7Cj4+ICsKPj4gKyAgICAgICAgaW5ub19oZG1p X3N5c19wb3dlcihoZG1pLCB0cnVlKTsKPj4gKyAgICAgICAgYnJlYWs7Cj4+ICsKPj4gKyAgICBj YXNlIExPV0VSX1BXUjoKPj4gKyAgICAgICAgaW5ub19oZG1pX3N5c19wb3dlcihoZG1pLCBmYWxz ZSk7Cj4+ICsgICAgICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfUEhZX0RSSVZFUiwgMHgwMCk7 Cj4+ICsgICAgICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfUEhZX1BSRV9FTVBIQVNJUywgMHgw MCk7Cj4+ICsgICAgICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfUEhZX0NIR19QV1IsIDB4MDAp Owo+PiArICAgICAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1BIWV9TWVNfQ1RMLCAweDE1KTsK Pj4gKwo+PiArICAgICAgICBicmVhazsKPj4gKwo+PiArICAgIGRlZmF1bHQ6Cj4+ICsgICAgICAg IGRldl9lcnIoaGRtaS0+ZGV2LCAiVW5rbm93biBwb3dlciBtb2RlICVkXG4iLCBtb2RlKTsKPj4g KyAgICB9Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGlubm9faGRtaV9yZXNldChzdHJ1Y3Qg aW5ub19oZG1pICpoZG1pKQo+PiArewo+PiArICAgIHUzMiB2YWw7Cj4+ICsgICAgdTMyIG1zazsK Pj4gKwo+PiArICAgIGhkbWlfbW9kYihoZG1pLCBIRE1JX1NZU19DVFJMLCBtX1JTVF9ESUdJVEFM LCB2X05PVF9SU1RfRElHSVRBTCk7Cj4+ICsgICAgdWRlbGF5KDEwMCk7Cj4+ICsKPj4gKyAgICBo ZG1pX21vZGIoaGRtaSwgSERNSV9TWVNfQ1RSTCwgbV9SU1RfQU5BTE9HLCB2X05PVF9SU1RfQU5B TE9HKTsKPj4gKyAgICB1ZGVsYXkoMTAwKTsKPj4gKwo+PiArICAgIG1zayA9IG1fUkVHX0NMS19J TlYgfCBtX1JFR19DTEtfU09VUkNFIHwgbV9QT1dFUiB8IG1fSU5UX1BPTDsKPj4gKyAgICB2YWwg PSB2X1JFR19DTEtfSU5WIHwgdl9SRUdfQ0xLX1NPVVJDRV9TWVMgfCB2X1BXUl9PTiB8IAo+PiB2 X0lOVF9QT0xfSElHSDsKPj4gKyAgICBoZG1pX21vZGIoaGRtaSwgSERNSV9TWVNfQ1RSTCwgbXNr LCB2YWwpOwo+PiArCj4+ICsgICAgaW5ub19oZG1pX3NldF9wd3JfbW9kZShoZG1pLCBOT1JNQUwp Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGlubm9faGRtaV9jb25maWdfdmlkZW9fYXZpKHN0 cnVjdCBpbm5vX2hkbWkgKmhkbWkpCj4+ICt7Cj4+ICsgICAgY2hhciBpbmZvW0hETUlfU0laRV9B VklfSU5GT0ZSQU1FXSA9IHswfTsKPj4gKyAgICBpbnQgYXZpX2NvbG9yX21vZGU7Cj4+ICsgICAg aW50IGk7Cj4+ICsKPj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX0NPTlRST0xfUEFDS0VU X0JVRl9JTkRFWCwgSU5GT0ZSQU1FX0FWSSk7Cj4+ICsKPj4gKyAgICBpbmZvWzBdID0gMHg4MjsK Pj4gKyAgICBpbmZvWzFdID0gMHgwMjsKPj4gKyAgICBpbmZvWzJdID0gMHgwRDsKPj4gKyAgICBp bmZvWzNdID0gaW5mb1swXSArIGluZm9bMV0gKyBpbmZvWzJdOwo+PiArCj4+ICsgICAgaWYgKGhk bWktPmhkbWlfZGF0YS5lbmNfb3V0X2Zvcm1hdCA9PSBIRE1JX0NPTE9SU1BBQ0VfUkdCKQo+PiAr ICAgICAgICBhdmlfY29sb3JfbW9kZSA9IEFWSV9DT0xPUl9NT0RFX1JHQjsKPj4gKyAgICBlbHNl IGlmIChoZG1pLT5oZG1pX2RhdGEuZW5jX291dF9mb3JtYXQgPT0gSERNSV9DT0xPUlNQQUNFX1lV VjQ0NCkKPj4gKyAgICAgICAgYXZpX2NvbG9yX21vZGUgPSBBVklfQ09MT1JfTU9ERV9ZQ0JDUjQ0 NDsKPj4gKyAgICBlbHNlIGlmIChoZG1pLT5oZG1pX2RhdGEuZW5jX291dF9mb3JtYXQgPT0gSERN SV9DT0xPUlNQQUNFX1lVVjQyMikKPj4gKyAgICAgICAgYXZpX2NvbG9yX21vZGUgPSBBVklfQ09M T1JfTU9ERV9ZQ0JDUjQyMjsKPj4gKyAgICBlbHNlCj4+ICsgICAgICAgIGF2aV9jb2xvcl9tb2Rl ID0gQVZJX0NPTE9SX01PREVfUkdCOwo+PiArCj4+ICsgICAgaW5mb1s0XSA9IChhdmlfY29sb3Jf bW9kZSA8PCA1KTsKPj4gKyAgICBpbmZvWzVdID0gKEFWSV9DT0xPUklNRVRSWV9OT19EQVRBIDw8 IDYpIHwKPj4gKyAgICAgICAgICAoQVZJX0NPREVEX0ZSQU1FX0FTUEVDVF9OT19EQVRBIDw8IDQp IHwKPj4gKyAgICAgICAgICBBQ1RJVkVfQVNQRUNUX1JBVEVfU0FNRV9BU19DT0RFRF9GUkFNRTsK Pj4gKwo+PiArICAgIGluZm9bNl0gPSAwOwo+PiArICAgIGluZm9bN10gPSBoZG1pLT5oZG1pX2Rh dGEudmljOwo+PiArCj4+ICsgICAgaWYgKGhkbWktPmhkbWlfZGF0YS52aWMgPT0gNiB8fCBoZG1p LT5oZG1pX2RhdGEudmljID09IDcgfHwKPj4gKyAgICAgICAgaGRtaS0+aGRtaV9kYXRhLnZpYyA9 PSAyMSB8fCBoZG1pLT5oZG1pX2RhdGEudmljID09IDIyKQo+PiArICAgICAgICBpbmZvWzhdID0g MTsKPj4gKyAgICBlbHNlCj4+ICsgICAgICAgIGluZm9bOF0gPSAwOwo+PiArCj4+ICsgICAgLyog Q2FsY3VsYXRlIGF2aSBpbmZvIGZyYW1lIGNoZWNLc3VtICovCj4+ICsgICAgZm9yIChpID0gNDsg aSA8IEhETUlfU0laRV9BVklfSU5GT0ZSQU1FOyBpKyspCj4+ICsgICAgICAgIGluZm9bM10gKz0g aW5mb1tpXTsKPj4gKyAgICBpbmZvWzNdID0gMHgxMDAgLSBpbmZvWzNdOwo+PiArCj4+ICsgICAg Zm9yIChpID0gMDsgaSA8IEhETUlfU0laRV9BVklfSU5GT0ZSQU1FOyBpKyspCj4+ICsgICAgICAg IGhkbWlfd3JpdGViKGhkbWksIEhETUlfQ09OVFJPTF9QQUNLRVRfQUREUiArIGksIGluZm9baV0p Owo+PiArCj4+ICsgICAgcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaW5ub19o ZG1pX2NvbmZpZ192aWRlb192c2koc3RydWN0IGlubm9faGRtaSAqaGRtaSkKPj4gK3sKPj4gKyAg ICBjaGFyIGluZm9bSERNSV9TSVpFX1ZTSV9JTkZPRlJBTUVdID0gezB9Owo+PiArICAgIGludCBp Owo+PiArCj4+ICsgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfUEFDS0VUX1NFTkRfQVVUTywgbV9Q QUNLRVRfVlNJX0VOLAo+PiArICAgICAgICAgIHZfUEFDS0VUX1ZTSV9FTigwKSk7Cj4+ICsKPj4g KyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX0NPTlRST0xfUEFDS0VUX0JVRl9JTkRFWCwgSU5G T0ZSQU1FX1ZTSSk7Cj4+ICsKPj4gKyAgICAvKiBIZWFkZXIgQnl0ZXMgKi8KPj4gKyAgICBpbmZv WzBdID0gMHg4MTsKPj4gKyAgICBpbmZvWzFdID0gMHgwMTsKPj4gKwo+PiArICAgIC8qIFBCMSAt IFBCMyBjb250YWluIHRoZSAyNGJpdCBJRUVFIFJlZ2lzdHJhdGlvbiBJZGVudGlmaWVyICovCj4+ ICsgICAgaW5mb1s0XSA9IDB4MDM7Cj4+ICsgICAgaW5mb1s1XSA9IDB4MGM7Cj4+ICsgICAgaW5m b1s2XSA9IDB4MDA7Cj4+ICsKPj4gKyAgICAvKiBQQjQgLSBIRE1JX1ZpZGVvX0Zvcm1hdCBpbnRv IGJpdHMgNzo1ICovCj4+ICsgICAgaW5mb1s3XSA9IDA7Cj4+ICsKPj4gKyAgICAvKgo+PiArICAg ICAqIFBCNSAtIERlcGVuZGluZyBvbiB0aGUgdmlkZW8gZm9ybWF0LCB0aGlzIGJ5dGUgd2lsbCBj b250YWluCj4+ICsgICAgICogZWl0aGVyIHRoZSBIRE1JX1ZJQyBjb2RlIGluIGJ1dHMgNzowLCBP UiB0aGUgM0RfU3RydWN0dXJlIGluCj4+ICsgICAgICogYml0cyA3OjQuCj4+ICsgICAgICovCj4+ ICsgICAgaW5mb1syXSA9IDB4MDYgLSAyOwo+PiArICAgIGluZm9bOF0gPSAwOwo+PiArICAgIGlu Zm9bOV0gPSAwOwo+PiArCj4+ICsgICAgaW5mb1szXSA9IGluZm9bMF0gKyBpbmZvWzFdICsgaW5m b1syXTsKPj4gKwo+PiArICAgIC8qIENhbGN1bGF0ZSBpbmZvIGZyYW1lIGNoZWNLc3VtICovCj4+ ICsgICAgZm9yIChpID0gNDsgaSA8IEhETUlfU0laRV9WU0lfSU5GT0ZSQU1FOyBpKyspCj4+ICsg ICAgICAgIGluZm9bM10gKz0gaW5mb1tpXTsKPj4gKyAgICBpbmZvWzNdID0gMHgxMDAgLSBpbmZv WzNdOwo+PiArCj4+ICsgICAgZm9yIChpID0gMDsgaSA8IEhETUlfU0laRV9WU0lfSU5GT0ZSQU1F OyBpKyspCj4+ICsgICAgICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfQ09OVFJPTF9QQUNLRVRf QUREUiArIGksIGluZm9baV0pOwo+PiArCj4+ICsgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfUEFD S0VUX1NFTkRfQVVUTywgbV9QQUNLRVRfVlNJX0VOLAo+PiArICAgICAgICAgIHZfUEFDS0VUX1ZT SV9FTigxKSk7Cj4+ICsKPj4gKyAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGlu dCBpbm5vX2hkbWlfY29uZmlnX3ZpZGVvX2NzYyhzdHJ1Y3QgaW5ub19oZG1pICpoZG1pKQo+PiAr ewo+PiArICAgIHN0cnVjdCBoZG1pX2RhdGFfaW5mbyAqZGF0YSA9ICZoZG1pLT5oZG1pX2RhdGE7 Cj4+ICsgICAgaW50IGMwX2MyX2NoYW5nZSA9IDA7Cj4+ICsgICAgaW50IGNzY19lbmFibGUgPSAw Owo+PiArICAgIGludCBjc2NfbW9kZSA9IDA7Cj4+ICsgICAgaW50IGF1dG9fY3NjID0gMDsKPj4g KyAgICBpbnQgdmFsdWU7Cj4+ICsgICAgaW50IGk7Cj4+ICsKPj4gKyAgICAvKiBJbnB1dCB2aWRl byBtb2RlIGlzIFNEUiBSR0IyNGJpdCwgZGF0YSBlbmFibGUgc2lnbmFsIGZyb20gCj4+IGV4dGVy bmFsICovCj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19DT05UUkwxLCB2X0RF X0VYVEVSTkFMIHwKPj4gKyAgICAgICAgICAgIHZfVklERU9fSU5QVVRfRk9STUFUKFZJREVPX0lO UFVUX1NEUl9SR0I0NDQpKTsKPj4gKwo+PiArICAgIC8qIElucHV0IGNvbG9yIGhhcmRjb2RlIHRv IFJHQiwgYW5kIG91dHB1dCBjb2xvciBoYXJkY29kZSB0byAKPj4gUkdCODg4ICovCj4+ICsgICAg dmFsdWUgPSB2X1ZJREVPX0lOUFVUX0JJVFMoVklERU9fSU5QVVRfOEJJVFMpIHwKPj4gKyAgICAg ICAgdl9WSURFT19PVVRQVVRfQ09MT1IoMCkgfAo+PiArICAgICAgICB2X1ZJREVPX0lOUFVUX0NT UCgwKTsKPj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0NPTlRSTDIsIHZhbHVl KTsKPj4gKwo+PiArICAgIGlmIChkYXRhLT5lbmNfb3V0X2Zvcm1hdCA9PSBkYXRhLT5lbmNfb3V0 X2Zvcm1hdCkgewo+PiArICAgICAgICBpZiAoKGRhdGEtPmVuY19pbl9mb3JtYXQgPT0gSERNSV9D T0xPUlNQQUNFX1JHQikgfHwKPj4gKyAgICAgICAgICAgIChkYXRhLT5lbmNfaW5fZm9ybWF0ID49 IEhETUlfQ09MT1JTUEFDRV9ZVVY0NDQpKSB7Cj4+ICsgICAgICAgICAgICB2YWx1ZSA9IHZfU09G X0RJU0FCTEUgfCB2X0NPTE9SX0RFUFRIX05PVF9JTkRJQ0FURUQoMSk7Cj4+ICsgICAgICAgICAg ICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0NPTlRSTDMsIHZhbHVlKTsKPj4gKwo+PiAr ICAgICAgICAgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfVklERU9fQ09OVFJMLAo+PiArICAgICAg ICAgICAgICAgICAgbV9WSURFT19BVVRPX0NTQyB8IG1fVklERU9fQzBfQzJfU1dBUCwKPj4gKyAg ICAgICAgICAgICAgICAgIHZfVklERU9fQVVUT19DU0MoQVVUT19DU0NfRElTQUJMRSkgfAo+PiAr ICAgICAgICAgICAgICAgICAgdl9WSURFT19DMF9DMl9TV0FQKEMwX0MyX0NIQU5HRV9ESVNBQkxF KSk7Cj4+ICsgICAgICAgICAgICByZXR1cm4gMDsKPj4gKyAgICAgICAgfQo+PiArICAgIH0KPj4g Kwo+PiArICAgIGlmIChkYXRhLT5jb2xvcmltZXRyeSA9PSBIRE1JX0NPTE9SSU1FVFJZX0lUVV82 MDEpIHsKPj4gKyAgICAgICAgaWYgKChkYXRhLT5lbmNfaW5fZm9ybWF0ID09IEhETUlfQ09MT1JT UEFDRV9SR0IpICYmCj4+ICsgICAgICAgICAgICAoZGF0YS0+ZW5jX291dF9mb3JtYXQgPT0gSERN SV9DT0xPUlNQQUNFX1lVVjQ0NCkpIHsKPj4gKyAgICAgICAgICAgIGNzY19tb2RlID0gQ1NDX1JH Ql8wXzI1NV9UT19JVFU2MDFfMTZfMjM1XzhCSVQ7Cj4+ICsgICAgICAgICAgICBhdXRvX2NzYyA9 IEFVVE9fQ1NDX0RJU0FCTEU7Cj4+ICsgICAgICAgICAgICBjMF9jMl9jaGFuZ2UgPSBDMF9DMl9D SEFOR0VfRElTQUJMRTsKPj4gKyAgICAgICAgICAgIGNzY19lbmFibGUgPSB2X0NTQ19FTkFCTEU7 Cj4+ICsgICAgICAgIH0gZWxzZSBpZiAoKGRhdGEtPmVuY19pbl9mb3JtYXQgPT0gSERNSV9DT0xP UlNQQUNFX1lVVjQ0NCkgJiYKPj4gKyAgICAgICAgICAgICAgIChkYXRhLT5lbmNfb3V0X2Zvcm1h dCA9PSBIRE1JX0NPTE9SU1BBQ0VfUkdCKSkgewo+PiArICAgICAgICAgICAgY3NjX21vZGUgPSBD U0NfSVRVNjAxXzE2XzIzNV9UT19SR0JfMF8yNTVfOEJJVDsKPj4gKyAgICAgICAgICAgIGF1dG9f Y3NjID0gQVVUT19DU0NfRU5BQkxFOwo+PiArICAgICAgICAgICAgYzBfYzJfY2hhbmdlID0gQzBf QzJfQ0hBTkdFX0RJU0FCTEU7Cj4+ICsgICAgICAgICAgICBjc2NfZW5hYmxlID0gdl9DU0NfRElT QUJMRTsKPj4gKyAgICAgICAgfQo+PiArICAgIH0gZWxzZSB7Cj4+ICsgICAgICAgIGlmICgoZGF0 YS0+ZW5jX2luX2Zvcm1hdCA9PSBIRE1JX0NPTE9SU1BBQ0VfUkdCKSAmJgo+PiArICAgICAgICAg ICAgKGRhdGEtPmVuY19vdXRfZm9ybWF0ID09IEhETUlfQ09MT1JTUEFDRV9ZVVY0NDQpKSB7Cj4+ ICsgICAgICAgICAgICBjc2NfbW9kZSA9IENTQ19SR0JfMF8yNTVfVE9fSVRVNzA5XzE2XzIzNV84 QklUOwo+PiArICAgICAgICAgICAgYXV0b19jc2MgPSBBVVRPX0NTQ19ESVNBQkxFOwo+PiArICAg ICAgICAgICAgYzBfYzJfY2hhbmdlID0gQzBfQzJfQ0hBTkdFX0RJU0FCTEU7Cj4+ICsgICAgICAg ICAgICBjc2NfZW5hYmxlID0gdl9DU0NfRU5BQkxFOwo+PiArICAgICAgICB9IGVsc2UgaWYgKChk YXRhLT5lbmNfaW5fZm9ybWF0ID09IEhETUlfQ09MT1JTUEFDRV9ZVVY0NDQpICYmCj4+ICsgICAg ICAgICAgICAgICAoZGF0YS0+ZW5jX291dF9mb3JtYXQgPT0gSERNSV9DT0xPUlNQQUNFX1JHQikp IHsKPj4gKyAgICAgICAgICAgIGNzY19tb2RlID0gQ1NDX0lUVTcwOV8xNl8yMzVfVE9fUkdCXzBf MjU1XzhCSVQ7Cj4+ICsgICAgICAgICAgICBhdXRvX2NzYyA9IEFVVE9fQ1NDX0VOQUJMRTsKPj4g KyAgICAgICAgICAgIGMwX2MyX2NoYW5nZSA9IEMwX0MyX0NIQU5HRV9ESVNBQkxFOwo+PiArICAg ICAgICAgICAgY3NjX2VuYWJsZSA9IHZfQ1NDX0RJU0FCTEU7Cj4+ICsgICAgICAgIH0KPj4gKyAg ICB9Cj4+ICsKPj4gKyAgICBmb3IgKGkgPSAwOyBpIDwgMjQ7IGkrKykKPj4gKyAgICAgICAgaGRt aV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19DU0NfQ09FRiArIGksCj4+ICsgICAgICAgICAgICAg ICAgY29lZmZfY3NjW2NzY19tb2RlXVtpXSk7Cj4+ICsKPj4gKyAgICB2YWx1ZSA9IHZfU09GX0RJ U0FCTEUgfCBjc2NfZW5hYmxlIHwgCj4+IHZfQ09MT1JfREVQVEhfTk9UX0lORElDQVRFRCgxKTsK Pj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0NPTlRSTDMsIHZhbHVlKTsKPj4g KyAgICBoZG1pX21vZGIoaGRtaSwgSERNSV9WSURFT19DT05UUkwsIG1fVklERU9fQVVUT19DU0Mg fAo+PiArICAgICAgICAgIG1fVklERU9fQzBfQzJfU1dBUCwgdl9WSURFT19BVVRPX0NTQyhhdXRv X2NzYykgfAo+PiArICAgICAgICAgIHZfVklERU9fQzBfQzJfU1dBUChjMF9jMl9jaGFuZ2UpKTsK Pj4gKwo+PiArICAgIHJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGlubm9faGRt aV9jb25maWdfdmlkZW9fdGltaW5nKHN0cnVjdCBpbm5vX2hkbWkgKmhkbWksCj4+ICsgICAgICAg ICAgICAgICAgICAgICBzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSkKPj4gK3sKPj4gKyAg ICBpbnQgdmFsdWU7Cj4+ICsKPj4gKyAgICAvKiBTZXQgZGV0YWlsIGV4dGVybmFsIHZpZGVvIHRp bWluZyBwb2xhcml0eSBhbmQgaW50ZXJsYWNlIG1vZGUgKi8KPj4gKyAgICB2YWx1ZSA9IHZfRVhU RVJBTkxfVklERU8oMSk7Cj4+ICsgICAgdmFsdWUgfD0gbW9kZS0+ZmxhZ3MgJiBEUk1fTU9ERV9G TEFHX1BIU1lOQyA/Cj4+ICsgICAgICAgICB2X0hTWU5DX1BPTEFSSVRZKDEpIDogdl9IU1lOQ19Q T0xBUklUWSgwKTsKPj4gKyAgICB2YWx1ZSB8PSBtb2RlLT5mbGFncyAmIERSTV9NT0RFX0ZMQUdf UFZTWU5DID8KPj4gKyAgICAgICAgIHZfVlNZTkNfUE9MQVJJVFkoMSkgOiB2X1ZTWU5DX1BPTEFS SVRZKDApOwo+PiArICAgIHZhbHVlIHw9IG1vZGUtPmZsYWdzICYgRFJNX01PREVfRkxBR19JTlRF UkxBQ0UgPwo+PiArICAgICAgICAgdl9JTkVUTEFDRSgxKSA6IHZfSU5FVExBQ0UoMCk7Cj4+ICsg ICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19USU1JTkdfQ1RMLCB2YWx1ZSk7Cj4+ICsK Pj4gKyAgICAvKiBTZXQgZGV0YWlsIGV4dGVybmFsIHZpZGVvIHRpbWluZyAqLwo+PiArICAgIHZh bHVlID0gbW9kZS0+aHRvdGFsOwo+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfVklERU9f RVhUX0hUT1RBTF9MLCB2YWx1ZSAmIDB4RkYpOwo+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhE TUlfVklERU9fRVhUX0hUT1RBTF9ILCAodmFsdWUgPj4gOCkgJiAweEZGKTsKPj4gKwo+PiArICAg IHZhbHVlID0gbW9kZS0+aHRvdGFsIC0gbW9kZS0+aGRpc3BsYXk7Cj4+ICsgICAgaGRtaV93cml0 ZWIoaGRtaSwgSERNSV9WSURFT19FWFRfSEJMQU5LX0wsIHZhbHVlICYgMHhGRik7Cj4+ICsgICAg aGRtaV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19FWFRfSEJMQU5LX0gsICh2YWx1ZSA+PiA4KSAm IDB4RkYpOwo+PiArCj4+ICsgICAgdmFsdWUgPSBtb2RlLT5oc3luY19zdGFydCAtIG1vZGUtPmhk aXNwbGF5Owo+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfVklERU9fRVhUX0hERUxBWV9M LCB2YWx1ZSAmIDB4RkYpOwo+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfVklERU9fRVhU X0hERUxBWV9ILCAodmFsdWUgPj4gOCkgJiAweEZGKTsKPj4gKwo+PiArICAgIHZhbHVlID0gbW9k ZS0+aHN5bmNfZW5kIC0gbW9kZS0+aHN5bmNfc3RhcnQ7Cj4+ICsgICAgaGRtaV93cml0ZWIoaGRt aSwgSERNSV9WSURFT19FWFRfSERVUkFUSU9OX0wsIHZhbHVlICYgMHhGRik7Cj4+ICsgICAgaGRt aV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19FWFRfSERVUkFUSU9OX0gsICh2YWx1ZSA+PiA4KSAm IDB4RkYpOwo+PiArCj4+ICsgICAgdmFsdWUgPSBtb2RlLT52dG90YWw7Cj4+ICsgICAgaGRtaV93 cml0ZWIoaGRtaSwgSERNSV9WSURFT19FWFRfVlRPVEFMX0wsIHZhbHVlICYgMHhGRik7Cj4+ICsg ICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19FWFRfVlRPVEFMX0gsICh2YWx1ZSA+PiA4 KSAmIDB4RkYpOwo+PiArCj4+ICsgICAgdmFsdWUgPSBtb2RlLT52dG90YWwgLSBtb2RlLT52ZGlz cGxheTsKPj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVPX0VYVF9WQkxBTkssIHZh bHVlICYgMHhGRik7Cj4+ICsKPj4gKyAgICB2YWx1ZSA9IG1vZGUtPnZzeW5jX3N0YXJ0IC0gbW9k ZS0+dmRpc3BsYXk7Cj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9WSURFT19FWFRfVkRF TEFZLCB2YWx1ZSAmIDB4RkYpOwo+PiArCj4+ICsgICAgdmFsdWUgPSBtb2RlLT52c3luY19lbmQg LSBtb2RlLT52c3luY19zdGFydDsKPj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX1ZJREVP X0VYVF9WRFVSQVRJT04sIHZhbHVlICYgMHhGRik7Cj4+ICsKPj4gKyAgICBoZG1pX3dyaXRlYiho ZG1pLCBIRE1JX1BIWV9QUkVfRElWX1JBVElPLCAweDFlKTsKPj4gKyAgICBoZG1pX3dyaXRlYiho ZG1pLCBIRE1JX1BIWV9GRUVEQkFDS19ESVZfUkFUSU9fTE9XLCAweDJjKTsKPj4gKyAgICBoZG1p X3dyaXRlYihoZG1pLCBIRE1JX1BIWV9GRUVEQkFDS19ESVZfUkFUSU9fSElHSCwgMHgwMSk7Cj4+ ICsKPj4gKyAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBpbm5vX2hkbWlf c2V0dXAoc3RydWN0IGlubm9faGRtaSAqaGRtaSwKPj4gKyAgICAgICAgICAgICAgIHN0cnVjdCBk cm1fZGlzcGxheV9tb2RlICptb2RlKQo+PiArewo+PiArICAgIGludCB2YWx1ZTsKCldoZXJlIGJl IHVzZWQ/CkkgZ3Vlc3MgeW91IHNob3VsZCByZW1vdmUgaXQuCgoKCi0KQ2Flc2FyCj4+ICsKPj4g KyAgICBoZG1pLT5oZG1pX2RhdGEudmljID0gZHJtX21hdGNoX2NlYV9tb2RlKG1vZGUpOwo+PiAr Cj4+ICsgICAgaGRtaS0+aGRtaV9kYXRhLmVuY19pbl9mb3JtYXQgPSBIRE1JX0NPTE9SU1BBQ0Vf UkdCOwo+PiArICAgIGhkbWktPmhkbWlfZGF0YS5lbmNfb3V0X2Zvcm1hdCA9IEhETUlfQ09MT1JT UEFDRV9SR0I7Cj4+ICsKPj4gKyAgICBpZiAoKGhkbWktPmhkbWlfZGF0YS52aWMgPT0gNikgfHwg KGhkbWktPmhkbWlfZGF0YS52aWMgPT0gNykgfHwKPj4gKyAgICAgICAgKGhkbWktPmhkbWlfZGF0 YS52aWMgPT0gMjEpIHx8IChoZG1pLT5oZG1pX2RhdGEudmljID09IDIyKSB8fAo+PiArICAgICAg ICAoaGRtaS0+aGRtaV9kYXRhLnZpYyA9PSAyKSB8fCAoaGRtaS0+aGRtaV9kYXRhLnZpYyA9PSAz KSB8fAo+PiArICAgICAgICAoaGRtaS0+aGRtaV9kYXRhLnZpYyA9PSAxNykgfHwgKGhkbWktPmhk bWlfZGF0YS52aWMgPT0gMTgpKQo+PiArICAgICAgICBoZG1pLT5oZG1pX2RhdGEuY29sb3JpbWV0 cnkgPSBIRE1JX0NPTE9SSU1FVFJZX0lUVV82MDE7Cj4+ICsgICAgZWxzZQo+PiArICAgICAgICBo ZG1pLT5oZG1pX2RhdGEuY29sb3JpbWV0cnkgPSBIRE1JX0NPTE9SSU1FVFJZX0lUVV83MDk7Cj4+ ICsKPj4gKyAgICAvKiBNdXRlIHZpZGVvIGFuZCBhdWRpbyBvdXRwdXQgKi8KPj4gKyAgICBoZG1p X21vZGIoaGRtaSwgSERNSV9BVl9NVVRFLCBtX0FVRElPX01VVEUgfCBtX1ZJREVPX0JMQUNLLAo+ PiArICAgICAgICAgIHZfQVVESU9fTVVURSgxKSB8IHZfVklERU9fTVVURSgxKSk7Cj4+ICsKPj4g KyAgICAvKiBTZXQgSERNSSBNb2RlICovCj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9I RENQX0NUUkwsCj4+ICsgICAgICAgICAgICB2X0hETUlfRFZJKGhkbWktPmhkbWlfZGF0YS5zaW5r X2lzX2hkbWkpKTsKPj4gKwo+PiArICAgIGlubm9faGRtaV9jb25maWdfdmlkZW9fdGltaW5nKGhk bWksIG1vZGUpOwo+PiArCj4+ICsgICAgaW5ub19oZG1pX2NvbmZpZ192aWRlb19jc2MoaGRtaSk7 Cj4+ICsKPj4gKyAgICBpZiAoaGRtaS0+aGRtaV9kYXRhLnNpbmtfaXNfaGRtaSkgewo+PiArICAg ICAgICBpbm5vX2hkbWlfY29uZmlnX3ZpZGVvX2F2aShoZG1pKTsKPj4gKyAgICAgICAgaW5ub19o ZG1pX2NvbmZpZ192aWRlb192c2koaGRtaSk7Cj4+ICsgICAgfQo+PiArCj4+ICsgICAgLyoKPj4g KyAgICAgKiBXaGVuIElQIGNvbnRyb2xsZXIgaGF2ZSBjb25maWd1cmVkIHRvIGFuIGFjY3VyYXRl IHZpZGVvCj4+ICsgICAgICogdGltaW5nLCB0aGVuIHRoZSBUTURTIGNsb2NrIHNvdXJjZSB3b3Vs ZCBiZSBzd2l0Y2hlZCB0bwo+PiArICAgICAqIERDTEtfTENEQywgc28gd2UgbmVlZCB0byBpbml0 IHRoZSBUTURTIHJhdGUgdG8gbW9kZSBwaXhlbAo+PiArICAgICAqIGNsb2NrIHJhdGUsIGFuZCBy ZWNvbmZpZ3VyZSB0aGUgRERDIGNsb2NrLgo+PiArICAgICAqLwo+PiArICAgIGhkbWktPnRtZHNf cmF0ZSA9IG1vZGUtPmNsb2NrICogMTAwMDsKPj4gKyAgICBpbm5vX2hkbWlfaTJjX2luaXQoaGRt aSk7Cj4+ICsKPj4gKyAgICAvKiBVbm11dGUgdmlkZW8gYW5kIGF1ZGlvIG91dHB1dCAqLwo+PiAr ICAgIGhkbWlfbW9kYihoZG1pLCBIRE1JX0FWX01VVEUsIG1fQVVESU9fTVVURSB8IG1fVklERU9f QkxBQ0ssCj4+ICsgICAgICAgICAgdl9BVURJT19NVVRFKDApIHwgdl9WSURFT19NVVRFKDApKTsK Pj4gKwo+PiArICAgIHJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBpbm5vX2hk bWlfZW5jb2Rlcl9tb2RlX3NldChzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIsCj4+ICsgICAg ICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlLAo+PiArICAg ICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqYWRqX21vZGUpCj4+ ICt7Cj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRtaSA9IHRvX2lubm9faGRtaShlbmNvZGVy KTsKPj4gKwo+PiArICAgIGlubm9faGRtaV9zZXR1cChoZG1pLCBhZGpfbW9kZSk7Cj4+ICsKPj4g KyAgICAvKiBTdG9yZSB0aGUgZGlzcGxheSBtb2RlIGZvciBwbHVnaW4vREtNUyBwb3dlcm9uIGV2 ZW50cyAqLwo+Cj4gSSB0aGluayBES01TIHNob3VsZCBiZSBEUE1TLgo+Cj4+ICsgICAgbWVtY3B5 KCZoZG1pLT5wcmV2aW91c19tb2RlLCBhZGpfbW9kZSwgCj4+IHNpemVvZihoZG1pLT5wcmV2aW91 c19tb2RlKSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGlubm9faGRtaV9lbmNvZGVyX2Vu YWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCj4+ICt7Cj4+ICsgICAgc3RydWN0IGlu bm9faGRtaSAqaGRtaSA9IHRvX2lubm9faGRtaShlbmNvZGVyKTsKPj4gKwo+PiArICAgIGlubm9f aGRtaV9zZXRfcHdyX21vZGUoaGRtaSwgTk9STUFMKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZv aWQgaW5ub19oZG1pX2VuY29kZXJfZGlzYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIp Cj4+ICt7Cj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRtaSA9IHRvX2lubm9faGRtaShlbmNv ZGVyKTsKPj4gKwo+PiArICAgIGlubm9faGRtaV9zZXRfcHdyX21vZGUoaGRtaSwgTE9XRVJfUFdS KTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgaW5ub19oZG1pX2VuY29kZXJfY29tbWl0KHN0 cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikKPj4gK3sKPj4gK30KPj4gKwo+PiArc3RhdGljIHZv aWQgaW5ub19oZG1pX2VuY29kZXJfcHJlcGFyZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIp Cj4+ICt7Cj4+ICsgICAgcm9ja2NoaXBfZHJtX2NydGNfbW9kZV9jb25maWcoZW5jb2Rlci0+Y3J0 YywgCj4+IERSTV9NT0RFX0NPTk5FQ1RPUl9IRE1JQSwKPj4gKyAgICAgICAgICAgICAgICAgICAg ICBST0NLQ0hJUF9PVVRfTU9ERV9QODg4KTsKPgo+IENhbiB5b3UgbW92ZSBtb2RlX2NvbmZpZyBp bnRvIGlubm9faGRtaV9lbmNvZGVyX2VuYWJsZSwgYW5kIHJlbW92ZSAKPiAucHJlcGFyZSBhbmQg LmNvbW1pdD8KPgo+PiArfQo+PiArCj4+ICtzdGF0aWMgYm9vbCBpbm5vX2hkbWlfZW5jb2Rlcl9t b2RlX2ZpeHVwKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwKPj4gKyAgICAgICAgICAgICAg ICAgICAgIGNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlLAo+PiArICAgICAgICAg ICAgICAgICAgICAgc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKmFkal9tb2RlKQo+PiArewo+PiAr ICAgIHJldHVybiB0cnVlOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgc3RydWN0IGRybV9lbmNvZGVy X2hlbHBlcl9mdW5jcyAKPj4gaW5ub19oZG1pX2VuY29kZXJfaGVscGVyX2Z1bmNzID0gewo+PiAr ICAgIC5lbmFibGUgICAgID0gaW5ub19oZG1pX2VuY29kZXJfZW5hYmxlLAo+PiArICAgIC5kaXNh YmxlICAgID0gaW5ub19oZG1pX2VuY29kZXJfZGlzYWJsZSwKPj4gKyAgICAubW9kZV9maXh1cCA9 IGlubm9faGRtaV9lbmNvZGVyX21vZGVfZml4dXAsCj4+ICsgICAgLm1vZGVfc2V0ICAgPSBpbm5v X2hkbWlfZW5jb2Rlcl9tb2RlX3NldCwKPj4gKyAgICAucHJlcGFyZSAgICA9IGlubm9faGRtaV9l bmNvZGVyX3ByZXBhcmUsCj4+ICsgICAgLmNvbW1pdCAgICAgPSBpbm5vX2hkbWlfZW5jb2Rlcl9j b21taXQsCj4KPiBPbiBkcm0gYXRvbWljLCBJIHRoaW5rIGlmIHN1cHBvcnQgLmVuYWJsZSBhbmQg LmRpc2FibGUgY2FsbGJhY2tzLCB0aGVuIAo+IC5wcmVwYXJlIGFuZCAuY29tbWl0IGlzIG5vdCBu ZWVkZWQuCj4KPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgZHJtX2VuY29kZXJfZnVuY3Mg aW5ub19oZG1pX2VuY29kZXJfZnVuY3MgPSB7Cj4+ICsgICAgLmRlc3Ryb3kgPSBkcm1fZW5jb2Rl cl9jbGVhbnVwLAo+PiArfTsKPj4gKwo+PiArc3RhdGljIGVudW0gZHJtX2Nvbm5lY3Rvcl9zdGF0 dXMKPj4gK2lubm9faGRtaV9jb25uZWN0b3JfZGV0ZWN0KHN0cnVjdCBkcm1fY29ubmVjdG9yICpj b25uZWN0b3IsIGJvb2wgZm9yY2UpCj4+ICt7Cj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRt aSA9IHRvX2lubm9faGRtaShjb25uZWN0b3IpOwo+PiArCj4+ICsgICAgcmV0dXJuIChoZG1pX3Jl YWRiKGhkbWksIEhETUlfU1RBVFVTKSAmIG1fSE9UUExVRykgPwo+PiArICAgICAgICBjb25uZWN0 b3Jfc3RhdHVzX2Nvbm5lY3RlZCA6IGNvbm5lY3Rvcl9zdGF0dXNfZGlzY29ubmVjdGVkOwo+PiAr fQo+PiArCj4+ICtzdGF0aWMgaW50IGlubm9faGRtaV9jb25uZWN0b3JfZ2V0X21vZGVzKHN0cnVj dCBkcm1fY29ubmVjdG9yIAo+PiAqY29ubmVjdG9yKQo+PiArewo+PiArICAgIHN0cnVjdCBpbm5v X2hkbWkgKmhkbWkgPSB0b19pbm5vX2hkbWkoY29ubmVjdG9yKTsKPj4gKyAgICBzdHJ1Y3QgZWRp ZCAqZWRpZDsKPj4gKyAgICBpbnQgcmV0ID0gMDsKPj4gKwo+PiArICAgIGlmICghaGRtaS0+ZGRj KQo+PiArICAgICAgICByZXR1cm4gMDsKPj4gKwo+PiArICAgIGVkaWQgPSBkcm1fZ2V0X2VkaWQo Y29ubmVjdG9yLCBoZG1pLT5kZGMpOwo+PiArICAgIGlmIChlZGlkKSB7Cj4+ICsgICAgICAgIGhk bWktPmhkbWlfZGF0YS5zaW5rX2lzX2hkbWkgPSBkcm1fZGV0ZWN0X2hkbWlfbW9uaXRvcihlZGlk KTsKPj4gKyAgICAgICAgaGRtaS0+aGRtaV9kYXRhLnNpbmtfaGFzX2F1ZGlvID0gCj4+IGRybV9k ZXRlY3RfbW9uaXRvcl9hdWRpbyhlZGlkKTsKPj4gKyAgICAgICAgZHJtX21vZGVfY29ubmVjdG9y X3VwZGF0ZV9lZGlkX3Byb3BlcnR5KGNvbm5lY3RvciwgZWRpZCk7Cj4+ICsgICAgICAgIHJldCA9 IGRybV9hZGRfZWRpZF9tb2Rlcyhjb25uZWN0b3IsIGVkaWQpOwo+PiArICAgICAgICBrZnJlZShl ZGlkKTsKPj4gKyAgICB9Cj4+ICsKPj4gKyAgICByZXR1cm4gcmV0Owo+PiArfQo+PiArCj4+ICtz dGF0aWMgZW51bSBkcm1fbW9kZV9zdGF0dXMKPj4gK2lubm9faGRtaV9jb25uZWN0b3JfbW9kZV92 YWxpZChzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yLAo+PiArICAgICAgICAgICAgICAg ICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlKQo+PiArewo+PiArICAgIHJldHVybiBN T0RFX09LOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgc3RydWN0IGRybV9lbmNvZGVyICoKPj4gK2lu bm9faGRtaV9jb25uZWN0b3JfYmVzdF9lbmNvZGVyKHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25u ZWN0b3IpCj4+ICt7Cj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRtaSA9IHRvX2lubm9faGRt aShjb25uZWN0b3IpOwo+PiArCj4+ICsgICAgcmV0dXJuICZoZG1pLT5lbmNvZGVyOwo+PiArfQo+ PiArCj4+ICtzdGF0aWMgaW50Cj4+ICtpbm5vX2hkbWlfcHJvYmVfc2luZ2xlX2Nvbm5lY3Rvcl9t b2RlcyhzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yLAo+PiArICAgICAgICAgICAgICAg ICAgICAgICB1aW50MzJfdCBtYXhYLCB1aW50MzJfdCBtYXhZKQo+PiArewo+PiArICAgIHJldHVy biBkcm1faGVscGVyX3Byb2JlX3NpbmdsZV9jb25uZWN0b3JfbW9kZXMoY29ubmVjdG9yLCAxOTIw LCAKPj4gMTA4MCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGlubm9faGRtaV9jb25uZWN0 b3JfZGVzdHJveShzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAKPj4gKmNvbm5lY3RvcikKPj4gK3sKPj4g KyAgICBkcm1fY29ubmVjdG9yX3VucmVnaXN0ZXIoY29ubmVjdG9yKTsKPj4gKyAgICBkcm1fY29u bmVjdG9yX2NsZWFudXAoY29ubmVjdG9yKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHN0cnVjdCBk cm1fY29ubmVjdG9yX2Z1bmNzIGlubm9faGRtaV9jb25uZWN0b3JfZnVuY3MgPSB7Cj4+ICsgICAg LmRwbXMgPSBkcm1fYXRvbWljX2hlbHBlcl9jb25uZWN0b3JfZHBtcywKPj4gKyAgICAuZmlsbF9t b2RlcyA9IGlubm9faGRtaV9wcm9iZV9zaW5nbGVfY29ubmVjdG9yX21vZGVzLAo+PiArICAgIC5k ZXRlY3QgPSBpbm5vX2hkbWlfY29ubmVjdG9yX2RldGVjdCwKPj4gKyAgICAuZGVzdHJveSA9IGlu bm9faGRtaV9jb25uZWN0b3JfZGVzdHJveSwKPj4gKyAgICAucmVzZXQgPSBkcm1fYXRvbWljX2hl bHBlcl9jb25uZWN0b3JfcmVzZXQsCj4+ICsgICAgLmF0b21pY19kdXBsaWNhdGVfc3RhdGUgPSAK Pj4gZHJtX2F0b21pY19oZWxwZXJfY29ubmVjdG9yX2R1cGxpY2F0ZV9zdGF0ZSwKPj4gKyAgICAu YXRvbWljX2Rlc3Ryb3lfc3RhdGUgPSBkcm1fYXRvbWljX2hlbHBlcl9jb25uZWN0b3JfZGVzdHJv eV9zdGF0ZSwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9oZWxw ZXJfZnVuY3MgCj4+IGlubm9faGRtaV9jb25uZWN0b3JfaGVscGVyX2Z1bmNzID0gewo+PiArICAg IC5nZXRfbW9kZXMgPSBpbm5vX2hkbWlfY29ubmVjdG9yX2dldF9tb2RlcywKPj4gKyAgICAubW9k ZV92YWxpZCA9IGlubm9faGRtaV9jb25uZWN0b3JfbW9kZV92YWxpZCwKPj4gKyAgICAuYmVzdF9l bmNvZGVyID0gaW5ub19oZG1pX2Nvbm5lY3Rvcl9iZXN0X2VuY29kZXIsCj4+ICt9Owo+PiArCj4+ ICtzdGF0aWMgaW50IGlubm9faGRtaV9yZWdpc3RlcihzdHJ1Y3QgZHJtX2RldmljZSAqZHJtLCBz dHJ1Y3QgCj4+IGlubm9faGRtaSAqaGRtaSkKPj4gK3sKPj4gKyAgICBzdHJ1Y3QgZHJtX2VuY29k ZXIgKmVuY29kZXIgPSAmaGRtaS0+ZW5jb2RlcjsKPj4gKwo+PiArICAgIGVuY29kZXItPnBvc3Np YmxlX2NydGNzID0gZHJtX29mX2ZpbmRfcG9zc2libGVfY3J0Y3MoZHJtLCAKPj4gaGRtaS0+ZGV2 LT5vZl9ub2RlKTsKPgo+IEtlZXAgODAgY2hhcmFjdGVycyA6LSkgLgo+Cj4+ICsgICAgLyoKPj4g KyAgICAgKiBJZiB3ZSBmYWlsZWQgdG8gZmluZCB0aGUgQ1JUQyhzKSB3aGljaCB0aGlzIGVuY29k ZXIgaXMKPj4gKyAgICAgKiBzdXBwb3NlZCB0byBiZSBjb25uZWN0ZWQgdG8sIGl0J3MgYmVjYXVz ZSB0aGUgQ1JUQyBoYXMKPj4gKyAgICAgKiBub3QgYmVlbiByZWdpc3RlcmVkIHlldC4gIERlZmVy IHByb2JpbmcsIGFuZCBob3BlIHRoYXQKPj4gKyAgICAgKiB0aGUgcmVxdWlyZWQgQ1JUQyBpcyBh ZGRlZCBsYXRlci4KPj4gKyAgICAgKi8KPj4gKyAgICBpZiAoZW5jb2Rlci0+cG9zc2libGVfY3J0 Y3MgPT0gMCkKPj4gKyAgICAgICAgcmV0dXJuIC1FUFJPQkVfREVGRVI7Cj4+ICsKPj4gKyAgICBk cm1fZW5jb2Rlcl9oZWxwZXJfYWRkKGVuY29kZXIsICZpbm5vX2hkbWlfZW5jb2Rlcl9oZWxwZXJf ZnVuY3MpOwo+PiArICAgIGRybV9lbmNvZGVyX2luaXQoZHJtLCBlbmNvZGVyLCAmaW5ub19oZG1p X2VuY29kZXJfZnVuY3MsCj4+ICsgICAgICAgICAgICAgRFJNX01PREVfRU5DT0RFUl9UTURTLCBO VUxMKTsKPj4gKwo+PiArICAgIGhkbWktPmNvbm5lY3Rvci5wb2xsZWQgPSBEUk1fQ09OTkVDVE9S X1BPTExfSFBEOwo+PiArCj4+ICsgICAgZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfYWRkKCZoZG1pLT5j b25uZWN0b3IsCj4+ICsgICAgICAgICAgICAgICAgICZpbm5vX2hkbWlfY29ubmVjdG9yX2hlbHBl cl9mdW5jcyk7Cj4+ICsgICAgZHJtX2Nvbm5lY3Rvcl9pbml0KGRybSwgJmhkbWktPmNvbm5lY3Rv ciwgCj4+ICZpbm5vX2hkbWlfY29ubmVjdG9yX2Z1bmNzLAo+PiArICAgICAgICAgICAgICAgRFJN X01PREVfQ09OTkVDVE9SX0hETUlBKTsKPj4gKwo+PiArICAgIGRybV9tb2RlX2Nvbm5lY3Rvcl9h dHRhY2hfZW5jb2RlcigmaGRtaS0+Y29ubmVjdG9yLCBlbmNvZGVyKTsKPj4gKwo+PiArICAgIHJl dHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaXJxcmV0dXJuX3QgaW5ub19oZG1pX2kyY19p cnEoc3RydWN0IGlubm9faGRtaSAqaGRtaSkKPj4gK3sKPj4gKyAgICBzdHJ1Y3QgaW5ub19oZG1p X2kyYyAqaTJjID0gaGRtaS0+aTJjOwo+PiArICAgIHU4IHN0YXQ7Cj4+ICsKPj4gKyAgICBzdGF0 ID0gaGRtaV9yZWFkYihoZG1pLCBIRE1JX0lOVEVSUlVQVF9TVEFUVVMxKTsKPj4gKyAgICBpZiAo IShzdGF0ICYgbV9JTlRfRURJRF9SRUFEWSkpCj4+ICsgICAgICAgIHJldHVybiBJUlFfTk9ORTsK Pj4gKwo+PiArICAgIC8qIENsZWFyIEhETUkgRURJRCBpbnRlcnJ1cHQgZmxhZyAqLwo+PiArICAg IGhkbWlfd3JpdGViKGhkbWksIEhETUlfSU5URVJSVVBUX1NUQVRVUzEsIG1fSU5UX0VESURfUkVB RFkpOwo+PiArCj4+ICsgICAgY29tcGxldGUoJmkyYy0+Y21wKTsKPj4gKwo+PiArICAgIHJldHVy biBJUlFfSEFORExFRDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGlycXJldHVybl90IGlubm9faGRt aV9oYXJkaXJxKGludCBpcnEsIHZvaWQgKmRldl9pZCkKPj4gK3sKPj4gKyAgICBzdHJ1Y3QgaW5u b19oZG1pICpoZG1pID0gZGV2X2lkOwo+PiArICAgIGlycXJldHVybl90IHJldCA9IElSUV9OT05F Owo+PiArICAgIHU4IGludGVycnVwdDsKPj4gKwo+PiArICAgIGlmIChoZG1pLT5pMmMpCj4+ICsg ICAgICAgIHJldCA9IGlubm9faGRtaV9pMmNfaXJxKGhkbWkpOwo+PiArCj4+ICsgICAgaW50ZXJy dXB0ID0gaGRtaV9yZWFkYihoZG1pLCBIRE1JX1NUQVRVUyk7Cj4+ICsgICAgaWYgKGludGVycnVw dCAmIG1fSU5UX0hPVFBMVUcpIHsKPj4gKyAgICAgICAgaGRtaV9tb2RiKGhkbWksIEhETUlfU1RB VFVTLCBtX0lOVF9IT1RQTFVHLCBtX0lOVF9IT1RQTFVHKTsKPj4gKyAgICAgICAgcmV0ID0gSVJR X1dBS0VfVEhSRUFEOwo+PiArICAgIH0KPj4gKwo+PiArICAgIHJldHVybiByZXQ7Cj4+ICt9Cj4+ ICsKPj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBpbm5vX2hkbWlfaXJxKGludCBpcnEsIHZvaWQgKmRl dl9pZCkKPj4gK3sKPj4gKyAgICBzdHJ1Y3QgaW5ub19oZG1pICpoZG1pID0gZGV2X2lkOwo+PiAr Cj4+ICsgICAgZHJtX2hlbHBlcl9ocGRfaXJxX2V2ZW50KGhkbWktPmNvbm5lY3Rvci5kZXYpOwo+ PiArCj4+ICsgICAgcmV0dXJuIElSUV9IQU5ETEVEOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50 IGlubm9faGRtaV9pMmNfd2FpdChzdHJ1Y3QgaW5ub19oZG1pICpoZG1pKQo+PiArewo+PiArICAg IHN0cnVjdCBpbm5vX2hkbWlfaTJjICppMmMgPSBoZG1pLT5pMmM7Cj4+ICsgICAgaW50IHN0YXQ7 Cj4+ICsKPj4gKyAgICBzdGF0ID0gd2FpdF9mb3JfY29tcGxldGlvbl90aW1lb3V0KCZpMmMtPmNt cCwgSFogLyAxMCk7Cj4+ICsgICAgaWYgKCFzdGF0KSB7Cj4+ICsgICAgICAgIHN0YXQgPSB3YWl0 X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoJmkyYy0+Y21wLCBIWiAvIDEwKTsKPj4gKyAgICAgICAg aWYgKCFzdGF0KQo+PiArICAgICAgICAgICAgcmV0dXJuIC1FQUdBSU47Cj4+ICsgICAgfQo+PiAr Cj4+ICsgICAgcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2ky Y19yZWFkKHN0cnVjdCBpbm5vX2hkbWkgKmhkbWksIHN0cnVjdCBpMmNfbXNnIAo+PiAqbXNncykK Pj4gK3sKPj4gKyAgICBpbnQgbGVuZ3RoID0gbXNncy0+bGVuOwo+PiArICAgIHU4ICpidWYgPSBt c2dzLT5idWY7Cj4+ICsgICAgaW50IHJldDsKPj4gKwo+PiArICAgIHJldCA9IGlubm9faGRtaV9p MmNfd2FpdChoZG1pKTsKPj4gKyAgICBpZiAocmV0KQo+PiArICAgICAgICByZXR1cm4gcmV0Owo+ PiArCj4+ICsgICAgd2hpbGUgKGxlbmd0aC0tKQo+PiArICAgICAgICAqYnVmKysgPSBoZG1pX3Jl YWRiKGhkbWksIEhETUlfRURJRF9GSUZPX0FERFIpOwo+PiArCj4+ICsgICAgcmV0dXJuIDA7Cj4+ ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2kyY193cml0ZShzdHJ1Y3QgaW5ub19o ZG1pICpoZG1pLCBzdHJ1Y3QgCj4+IGkyY19tc2cgKm1zZ3MpCj4+ICt7Cj4+ICsgICAgc3RydWN0 IGlubm9faGRtaV9pMmMgKmkyYyA9IGhkbWktPmkyYzsKPj4gKwo+PiArICAgIC8qCj4+ICsgICAg ICogVGhlIEREQyBtb2R1bGUgb25seSBzdXBwb3J0IHJlYWQgRURJRCBtZXNzYWdlLCBzbwo+PiAr ICAgICAqIHdlIGFzc3VtZSB0aGF0IGVhY2ggd29yZCB3cml0ZSB0byB0aGlzIGkyYyBhZGFwdGVy Cj4+ICsgICAgICogc2hvdWxkIGJlIHRoZSBvZmZzZXQgb2YgRURJRCB3b3JkIGFkZHJlc3MuCj4+ ICsgICAgICovCj4+ICsgICAgaWYgKChtc2dzLT5sZW4gIT0gMSkgfHwKPj4gKyAgICAgICAgKCht c2dzLT5hZGRyICE9IEREQ19BRERSKSAmJiAobXNncy0+YWRkciAhPSBERENfU0VHTUVOVF9BRERS KSkpCj4+ICsgICAgICAgIHJldHVybiAtRUlOVkFMOwo+PiArCj4+ICsgICAgcmVpbml0X2NvbXBs ZXRpb24oJmkyYy0+Y21wKTsKPj4gKwo+PiArICAgIGlmIChtc2dzLT5hZGRyID09IEREQ19TRUdN RU5UX0FERFIpCj4+ICsgICAgICAgIGhkbWktPmkyYy0+c2VnbWVudF9hZGRyID0gbXNncy0+YnVm WzBdOwo+PiArICAgIGlmIChtc2dzLT5hZGRyID09IEREQ19BRERSKQo+PiArICAgICAgICBoZG1p LT5pMmMtPmRkY19hZGRyID0gbXNncy0+YnVmWzBdOwo+PiArCj4+ICsgICAgLyogU2V0IGVkaWQg ZmlmbyBmaXJzdCBhZGRyICovCj4+ICsgICAgaGRtaV93cml0ZWIoaGRtaSwgSERNSV9FRElEX0ZJ Rk9fT0ZGU0VULCAweDAwKTsKPj4gKwo+PiArICAgIC8qIFNldCBlZGlkIHdvcmQgYWRkcmVzcyAw eDAwLzB4ODAgKi8KPj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBIRE1JX0VESURfV09SRF9BRERS LCBoZG1pLT5pMmMtPmRkY19hZGRyKTsKPj4gKwo+PiArICAgIC8qIFNldCBlZGlkIHNlZ21lbnQg cG9pbnRlciAqLwo+PiArICAgIGhkbWlfd3JpdGViKGhkbWksIEhETUlfRURJRF9TRUdNRU5UX1BP SU5URVIsIAo+PiBoZG1pLT5pMmMtPnNlZ21lbnRfYWRkcik7Cj4+ICsKPj4gKyAgICByZXR1cm4g MDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBpbm5vX2hkbWlfaTJjX3hmZXIoc3RydWN0IGky Y19hZGFwdGVyICphZGFwLAo+PiArICAgICAgICAgICAgICAgICAgc3RydWN0IGkyY19tc2cgKm1z Z3MsIGludCBudW0pCj4+ICt7Cj4+ICsgICAgc3RydWN0IGlubm9faGRtaSAqaGRtaSA9IGkyY19n ZXRfYWRhcGRhdGEoYWRhcCk7Cj4+ICsgICAgc3RydWN0IGlubm9faGRtaV9pMmMgKmkyYyA9IGhk bWktPmkyYzsKPj4gKyAgICBpbnQgaSwgcmV0ID0gMDsKPj4gKwo+PiArICAgIG11dGV4X2xvY2so JmkyYy0+bG9jayk7Cj4+ICsKPj4gKyAgICAvKiBDbGVhciB0aGUgRURJRCBpbnRlcnJ1cHQgZmxh ZyBhbmQgdW5tdXRlIHRoZSBpbnRlcnJ1cHQgKi8KPj4gKyAgICBoZG1pX3dyaXRlYihoZG1pLCBI RE1JX0lOVEVSUlVQVF9NQVNLMSwgbV9JTlRfRURJRF9SRUFEWSk7Cj4+ICsgICAgaGRtaV93cml0 ZWIoaGRtaSwgSERNSV9JTlRFUlJVUFRfU1RBVFVTMSwgbV9JTlRfRURJRF9SRUFEWSk7Cj4+ICsK Pj4gKyAgICBmb3IgKGkgPSAwOyBpIDwgbnVtOyBpKyspIHsKPj4gKyAgICAgICAgZGV2X2RiZyho ZG1pLT5kZXYsICJ4ZmVyOiBudW06ICVkLyVkLCBsZW46ICVkLCBmbGFnczogJSN4XG4iLAo+PiAr ICAgICAgICAgICAgaSArIDEsIG51bSwgbXNnc1tpXS5sZW4sIG1zZ3NbaV0uZmxhZ3MpOwo+PiAr Cj4+ICsgICAgICAgIGlmIChtc2dzW2ldLmZsYWdzICYgSTJDX01fUkQpCj4+ICsgICAgICAgICAg ICByZXQgPSBpbm5vX2hkbWlfaTJjX3JlYWQoaGRtaSwgJm1zZ3NbaV0pOwo+PiArICAgICAgICBl bHNlCj4+ICsgICAgICAgICAgICByZXQgPSBpbm5vX2hkbWlfaTJjX3dyaXRlKGhkbWksICZtc2dz W2ldKTsKPj4gKwo+PiArICAgICAgICBpZiAocmV0IDwgMCkKPj4gKyAgICAgICAgICAgIGJyZWFr Owo+PiArICAgIH0KPj4gKwo+PiArICAgIGlmICghcmV0KQo+PiArICAgICAgICByZXQgPSBudW07 Cj4+ICsKPj4gKyAgICAvKiBNdXRlIEhETUkgRURJRCBpbnRlcnJ1cHQgKi8KPj4gKyAgICBoZG1p X3dyaXRlYihoZG1pLCBIRE1JX0lOVEVSUlVQVF9NQVNLMSwgMCk7Cj4+ICsKPj4gKyAgICBtdXRl eF91bmxvY2soJmkyYy0+bG9jayk7Cj4+ICsKPj4gKyAgICByZXR1cm4gcmV0Owo+PiArfQo+PiAr Cj4+ICtzdGF0aWMgdTMyIGlubm9faGRtaV9pMmNfZnVuYyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFk YXB0ZXIpCj4+ICt7Cj4+ICsgICAgcmV0dXJuIEkyQ19GVU5DX0kyQyB8IEkyQ19GVU5DX1NNQlVT X0VNVUw7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgaTJjX2FsZ29yaXRobSBp bm5vX2hkbWlfYWxnb3JpdGhtID0gewo+PiArICAgIC5tYXN0ZXJfeGZlciAgICA9IGlubm9faGRt aV9pMmNfeGZlciwKPj4gKyAgICAuZnVuY3Rpb25hbGl0eSAgICA9IGlubm9faGRtaV9pMmNfZnVu YywKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmlubm9faGRtaV9p MmNfYWRhcHRlcihzdHJ1Y3QgaW5ub19oZG1pIAo+PiAqaGRtaSkKPj4gK3sKPj4gKyAgICBzdHJ1 Y3QgaTJjX2FkYXB0ZXIgKmFkYXA7Cj4+ICsgICAgc3RydWN0IGlubm9faGRtaV9pMmMgKmkyYzsK Pj4gKyAgICBpbnQgcmV0Owo+PiArCj4+ICsgICAgaTJjID0gZGV2bV9remFsbG9jKGhkbWktPmRl diwgc2l6ZW9mKCppMmMpLCBHRlBfS0VSTkVMKTsKPj4gKyAgICBpZiAoIWkyYykKPj4gKyAgICAg ICAgcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7Cj4+ICsKPj4gKyAgICBtdXRleF9pbml0KCZpMmMt PmxvY2spOwo+PiArICAgIGluaXRfY29tcGxldGlvbigmaTJjLT5jbXApOwo+PiArCj4+ICsgICAg YWRhcCA9ICZpMmMtPmFkYXA7Cj4+ICsgICAgYWRhcC0+Y2xhc3MgPSBJMkNfQ0xBU1NfRERDOwo+ PiArICAgIGFkYXAtPm93bmVyID0gVEhJU19NT0RVTEU7Cj4+ICsgICAgYWRhcC0+ZGV2LnBhcmVu dCA9IGhkbWktPmRldjsKPj4gKyAgICBhZGFwLT5kZXYub2Zfbm9kZSA9IGhkbWktPmRldi0+b2Zf bm9kZTsKPj4gKyAgICBhZGFwLT5hbGdvID0gJmlubm9faGRtaV9hbGdvcml0aG07Cj4+ICsgICAg c3RybGNweShhZGFwLT5uYW1lLCAiSW5ubyBIRE1JIiwgc2l6ZW9mKGFkYXAtPm5hbWUpKTsKPj4g KyAgICBpMmNfc2V0X2FkYXBkYXRhKGFkYXAsIGhkbWkpOwo+PiArCj4+ICsgICAgcmV0ID0gaTJj X2FkZF9hZGFwdGVyKGFkYXApOwo+PiArICAgIGlmIChyZXQpIHsKPj4gKyAgICAgICAgZGV2X3dh cm4oaGRtaS0+ZGV2LCAiY2Fubm90IGFkZCAlcyBJMkMgYWRhcHRlclxuIiwgYWRhcC0+bmFtZSk7 Cj4+ICsgICAgICAgIGRldm1fa2ZyZWUoaGRtaS0+ZGV2LCBpMmMpOwo+PiArICAgICAgICByZXR1 cm4gRVJSX1BUUihyZXQpOwo+PiArICAgIH0KPj4gKwo+PiArICAgIGhkbWktPmkyYyA9IGkyYzsK Pj4gKwo+PiArICAgIGRldl9pbmZvKGhkbWktPmRldiwgInJlZ2lzdGVyZWQgJXMgSTJDIGJ1cyBk cml2ZXJcbiIsIGFkYXAtPm5hbWUpOwo+PiArCj4+ICsgICAgcmV0dXJuIGFkYXA7Cj4+ICt9Cj4+ ICsKPj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2JpbmQoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1 Y3QgZGV2aWNlICptYXN0ZXIsCj4+ICsgICAgICAgICAgICAgICAgIHZvaWQgKmRhdGEpCj4+ICt7 Cj4+ICsgICAgc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IHRvX3BsYXRmb3JtX2Rldmlj ZShkZXYpOwo+PiArICAgIHN0cnVjdCBkcm1fZGV2aWNlICpkcm0gPSBkYXRhOwo+PiArICAgIHN0 cnVjdCBpbm5vX2hkbWkgKmhkbWk7Cj4+ICsgICAgc3RydWN0IHJlc291cmNlICppb3JlczsKPj4g KyAgICBpbnQgaXJxOwo+PiArICAgIGludCByZXQ7Cj4+ICsKPj4gKyAgICBoZG1pID0gZGV2bV9r emFsbG9jKGRldiwgc2l6ZW9mKCpoZG1pKSwgR0ZQX0tFUk5FTCk7Cj4+ICsgICAgaWYgKCFoZG1p KQo+PiArICAgICAgICByZXR1cm4gLUVOT01FTTsKPj4gKwo+PiArICAgIGhkbWktPmRldiA9IGRl djsKPj4gKyAgICBoZG1pLT5kcm1fZGV2ID0gZHJtOwo+PiArCj4+ICsgICAgaW9yZXMgPSBwbGF0 Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOwo+PiArICAgIGlmICgh aW9yZXMpCj4+ICsgICAgICAgIHJldHVybiAtRU5YSU87Cj4+ICsKPj4gKyAgICBoZG1pLT5yZWdz ID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKGRldiwgaW9yZXMpOwo+PiArICAgIGlmIChJU19FUlIo aGRtaS0+cmVncykpCj4+ICsgICAgICAgIHJldHVybiBQVFJfRVJSKGhkbWktPnJlZ3MpOwo+PiAr Cj4+ICsgICAgaGRtaS0+cGNsayA9IGRldm1fY2xrX2dldChoZG1pLT5kZXYsICJwY2xrIik7Cj4+ ICsgICAgaWYgKElTX0VSUihoZG1pLT5wY2xrKSkgewo+PiArICAgICAgICBkZXZfZXJyKGhkbWkt PmRldiwgIlVuYWJsZSB0byBnZXQgSERNSSBwY2xrIGNsa1xuIik7Cj4+ICsgICAgICAgIHJldHVy biBQVFJfRVJSKGhkbWktPnBjbGspOwo+PiArICAgIH0KPj4gKwo+PiArICAgIHJldCA9IGNsa19w cmVwYXJlX2VuYWJsZShoZG1pLT5wY2xrKTsKPj4gKyAgICBpZiAocmV0KSB7Cj4+ICsgICAgICAg IGRldl9lcnIoaGRtaS0+ZGV2LCAiQ2Fubm90IGVuYWJsZSBIRE1JIHBjbGsgY2xvY2s6ICVkXG4i LCByZXQpOwo+PiArICAgICAgICByZXR1cm4gcmV0Owo+PiArICAgIH0KPj4gKwo+PiArICAgIGly cSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7Cj4+ICsgICAgaWYgKGlycSA8IDApCj4+ICsg ICAgICAgIHJldHVybiBpcnE7Cj4+ICsKPj4gKyAgICBpbm5vX2hkbWlfcmVzZXQoaGRtaSk7Cj4+ ICsKPj4gKyAgICBoZG1pLT5kZGMgPSBpbm5vX2hkbWlfaTJjX2FkYXB0ZXIoaGRtaSk7Cj4+ICsg ICAgaWYgKElTX0VSUihoZG1pLT5kZGMpKSB7Cj4+ICsgICAgICAgIGhkbWktPmRkYyA9IE5VTEw7 Cj4+ICsgICAgICAgIHJldHVybiBQVFJfRVJSKGhkbWktPmRkYyk7Cj4+ICsgICAgfQo+PiArCj4+ ICsgICAgLyoKPj4gKyAgICAgKiBXaGVuIElQIGNvbnRyb2xsZXIgaGF2ZW4ndCBjb25maWd1cmVk IHRvIGFuIGFjY3VyYXRlIHZpZGVvCj4+ICsgICAgICogdGltaW5nLCB0aGVuIHRoZSBUTURTIGNs b2NrIHNvdXJjZSB3b3VsZCBiZSBzd2l0Y2hlZCB0bwo+PiArICAgICAqIFBDTEtfSERNSSwgc28g d2UgbmVlZCB0byBpbml0IHRoZSBUTURTIHJhdGUgdG8gUENMSyByYXRlLAo+PiArICAgICAqIGFu ZCByZWNvbmZpZ3VyZSB0aGUgRERDIGNsb2NrLgo+PiArICAgICAqLwo+PiArICAgIGhkbWktPnRt ZHNfcmF0ZSA9IGNsa19nZXRfcmF0ZShoZG1pLT5wY2xrKTsKPj4gKyAgICBpbm5vX2hkbWlfaTJj X2luaXQoaGRtaSk7Cj4+ICsKPj4gKyAgICByZXQgPSBpbm5vX2hkbWlfcmVnaXN0ZXIoZHJtLCBo ZG1pKTsKPj4gKyAgICBpZiAocmV0KQo+PiArICAgICAgICByZXR1cm4gcmV0Owo+PiArCj4+ICsg ICAgZGV2X3NldF9kcnZkYXRhKGRldiwgaGRtaSk7Cj4+ICsKPj4gKyAgICAvKiBVbm11dGUgaG90 cGx1ZyBpbnRlcnJ1cHQgKi8KPj4gKyAgICBoZG1pX21vZGIoaGRtaSwgSERNSV9TVEFUVVMsIG1f TUFTS19JTlRfSE9UUExVRywgCj4+IHZfTUFTS19JTlRfSE9UUExVRygxKSk7Cj4+ICsKPj4gKyAg ICByZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRfaXJxKGRldiwgaXJxLCBpbm5vX2hkbWlfaGFy ZGlycSwKPj4gKyAgICAgICAgICAgICAgICAgICAgaW5ub19oZG1pX2lycSwgSVJRRl9TSEFSRUQs Cj4+ICsgICAgICAgICAgICAgICAgICAgIGRldl9uYW1lKGRldiksIGhkbWkpOwo+PiArCj4+ICsg ICAgcmV0dXJuIHJldDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgaW5ub19oZG1pX3VuYmlu ZChzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2UgKm1hc3RlciwKPj4gKyAgICAgICAg ICAgICAgICAgdm9pZCAqZGF0YSkKPj4gK3sKPj4gKyAgICBzdHJ1Y3QgaW5ub19oZG1pICpoZG1p ID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4+ICsKPj4gKyBoZG1pLT5jb25uZWN0b3IuZnVuY3Mt PmRlc3Ryb3koJmhkbWktPmNvbm5lY3Rvcik7Cj4+ICsgICAgaGRtaS0+ZW5jb2Rlci5mdW5jcy0+ ZGVzdHJveSgmaGRtaS0+ZW5jb2Rlcik7Cj4+ICsKPj4gKyAgICBjbGtfZGlzYWJsZV91bnByZXBh cmUoaGRtaS0+cGNsayk7Cj4+ICsgICAgaTJjX3B1dF9hZGFwdGVyKGhkbWktPmRkYyk7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY29tcG9uZW50X29wcyBpbm5vX2hkbWlfb3Bz ID0gewo+PiArICAgIC5iaW5kICAgID0gaW5ub19oZG1pX2JpbmQsCj4+ICsgICAgLnVuYmluZCAg ICA9IGlubm9faGRtaV91bmJpbmQsCj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgaW50IGlubm9faGRt aV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+PiArewo+PiArICAgIHJldHVy biBjb21wb25lbnRfYWRkKCZwZGV2LT5kZXYsICZpbm5vX2hkbWlfb3BzKTsKPj4gK30KPj4gKwo+ PiArc3RhdGljIGludCBpbm5vX2hkbWlfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk ZXYpCj4+ICt7Cj4+ICsgICAgY29tcG9uZW50X2RlbCgmcGRldi0+ZGV2LCAmaW5ub19oZG1pX29w cyk7Cj4+ICsKPj4gKyAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0 cnVjdCBvZl9kZXZpY2VfaWQgaW5ub19oZG1pX2R0X2lkc1tdID0gewo+PiArICAgIHsgLmNvbXBh dGlibGUgPSAicm9ja2NoaXAscmszMDM2LWlubm8taGRtaSIsCj4+ICsgICAgfSwKPj4gKyAgICB7 fSwKPj4gK307Cj4+ICtNT0RVTEVfREVWSUNFX1RBQkxFKG9mLCBpbm5vX2hkbWlfZHRfaWRzKTsK Pj4gKwo+PiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgaW5ub19oZG1pX2RyaXZlciA9 IHsKPj4gKyAgICAucHJvYmUgID0gaW5ub19oZG1pX3Byb2JlLAo+PiArICAgIC5yZW1vdmUgPSBp bm5vX2hkbWlfcmVtb3ZlLAo+PiArICAgIC5kcml2ZXIgPSB7Cj4+ICsgICAgICAgIC5uYW1lID0g Imlubm9oZG1pLXJvY2tjaGlwIiwKPj4gKyAgICAgICAgLm9mX21hdGNoX3RhYmxlID0gaW5ub19o ZG1pX2R0X2lkcywKPj4gKyAgICB9LAo+PiArfTsKPj4gKwo+PiArbW9kdWxlX3BsYXRmb3JtX2Ry aXZlcihpbm5vX2hkbWlfZHJpdmVyKTsKPj4gKwo+PiArTU9EVUxFX0FVVEhPUigiWmhlbmcgWWFu ZyA8emhlbmd5YW5nQHJvY2stY2hpcHMuY29tPiIpOwo+PiArTU9EVUxFX0FVVEhPUigiWWFraXIg WWFuZyA8eWtrQHJvY2stY2hpcHMuY29tPiIpOwo+PiArTU9EVUxFX0RFU0NSSVBUSU9OKCJSb2Nr Y2hpcCBTcGVjaWZpYyBJTk5PLUhETUkgRHJpdmVyIik7Cj4+ICtNT0RVTEVfTElDRU5TRSgiR1BM Iik7Cj4+ICtNT0RVTEVfQUxJQVMoInBsYXRmb3JtOmlubm9oZG1pLXJvY2tjaGlwIik7Cj4+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmggCj4+IGIvZHJp dmVycy9ncHUvZHJtL3JvY2tjaGlwL2lubm9faGRtaS5oCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0 Cj4+IGluZGV4IDAwMDAwMDAuLjRmZjE3YWQKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2 ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmgKPj4gQEAgLTAsMCArMSwzNjQgQEAKPj4g Ky8qCj4+ICsgKiBDb3B5cmlnaHQgKEMpIEZ1emhvdSBSb2NrY2hpcCBFbGVjdHJvbmljcyBDby5M dGQKPj4gKyAqICAgIFpoZW5nIFlhbmcgPHpoZW5neWFuZ0Byb2NrLWNoaXBzLmNvbT4KPj4gKyAq ICAgIFlha2lyIFlhbmcgPHlra0Byb2NrLWNoaXBzLmNvbT4KPj4gKyAqCj4+ICsgKiBUaGlzIHNv ZnR3YXJlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVi bGljCj4+ICsgKiBMaWNlbnNlIHZlcnNpb24gMiwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNv ZnR3YXJlIEZvdW5kYXRpb24sIGFuZAo+PiArICogbWF5IGJlIGNvcGllZCwgZGlzdHJpYnV0ZWQs IGFuZCBtb2RpZmllZCB1bmRlciB0aG9zZSB0ZXJtcy4KPj4gKyAqCj4+ICsgKiBUaGlzIHByb2dy YW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKPj4g KyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdh cnJhbnR5IG9mCj4+ICsgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNV TEFSIFBVUlBPU0UuICBTZWUgdGhlCj4+ICsgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBm b3IgbW9yZSBkZXRhaWxzLgo+PiArICovCj4+ICsKPj4gKyNpZm5kZWYgX19JTk5PX0hETUlfSF9f Cj4+ICsjZGVmaW5lIF9fSU5OT19IRE1JX0hfXwo+PiArCj4+ICsjZGVmaW5lIEREQ19TRUdNRU5U X0FERFIgICAgICAgIDB4MzAKPj4gKwo+PiArZW51bSBQV1JfTU9ERSB7Cj4+ICsgICAgTk9STUFM LAo+PiArICAgIExPV0VSX1BXUiwKPj4gK307Cj4+ICsKPj4gKyNkZWZpbmUgSERNSV9TQ0xfUkFU RSAgICAgICAgICAgICgxMDAqMTAwMCkKPj4gKyNkZWZpbmUgRERDX0JVU19GUkVRX0wgICAgICAg ICAgICAweDRiCj4+ICsjZGVmaW5lIEREQ19CVVNfRlJFUV9IICAgICAgICAgICAgMHg0Ywo+PiAr Cj4+ICsjZGVmaW5lIEhETUlfU1lTX0NUUkwgICAgICAgICAgICAweDAwCj4+ICsjZGVmaW5lIG1f UlNUX0FOQUxPRyAgICAgICAgICAgICgxIDw8IDYpCj4+ICsjZGVmaW5lIHZfUlNUX0FOQUxPRyAg ICAgICAgICAgICgwIDw8IDYpCj4+ICsjZGVmaW5lIHZfTk9UX1JTVF9BTkFMT0cgICAgICAgICgx IDw8IDYpCj4+ICsjZGVmaW5lIG1fUlNUX0RJR0lUQUwgICAgICAgICAgICAoMSA8PCA1KQo+PiAr I2RlZmluZSB2X1JTVF9ESUdJVEFMICAgICAgICAgICAgKDAgPDwgNSkKPj4gKyNkZWZpbmUgdl9O T1RfUlNUX0RJR0lUQUwgICAgICAgICgxIDw8IDUpCj4+ICsjZGVmaW5lIG1fUkVHX0NMS19JTlYg ICAgICAgICAgICAoMSA8PCA0KQo+PiArI2RlZmluZSB2X1JFR19DTEtfTk9UX0lOViAgICAgICAg KDAgPDwgNCkKPj4gKyNkZWZpbmUgdl9SRUdfQ0xLX0lOViAgICAgICAgICAgICgxIDw8IDQpCj4+ ICsjZGVmaW5lIG1fVkNMS19JTlYgICAgICAgICAgICAoMSA8PCAzKQo+PiArI2RlZmluZSB2X1ZD TEtfTk9UX0lOViAgICAgICAgICAgICgwIDw8IDMpCj4+ICsjZGVmaW5lIHZfVkNMS19JTlYgICAg ICAgICAgICAoMSA8PCAzKQo+PiArI2RlZmluZSBtX1JFR19DTEtfU09VUkNFICAgICAgICAoMSA8 PCAyKQo+PiArI2RlZmluZSB2X1JFR19DTEtfU09VUkNFX1RNRFMgICAgICAgICgwIDw8IDIpCj4+ ICsjZGVmaW5lIHZfUkVHX0NMS19TT1VSQ0VfU1lTICAgICAgICAoMSA8PCAyKQo+PiArI2RlZmlu ZSBtX1BPV0VSICAgICAgICAgICAgICAgICgxIDw8IDEpCj4+ICsjZGVmaW5lIHZfUFdSX09OICAg ICAgICAgICAgKDAgPDwgMSkKPj4gKyNkZWZpbmUgdl9QV1JfT0ZGICAgICAgICAgICAgKDEgPDwg MSkKPj4gKyNkZWZpbmUgbV9JTlRfUE9MICAgICAgICAgICAgKDEgPDwgMCkKPj4gKyNkZWZpbmUg dl9JTlRfUE9MX0hJR0ggICAgICAgICAgICAxCj4+ICsjZGVmaW5lIHZfSU5UX1BPTF9MT1cgICAg ICAgICAgICAwCj4+ICsKPj4gKyNkZWZpbmUgSERNSV9WSURFT19DT05UUkwxICAgICAgICAweDAx Cj4+ICsjZGVmaW5lIG1fVklERU9fSU5QVVRfRk9STUFUICAgICAgICAoNyA8PCAxKQo+PiArI2Rl ZmluZSBtX0RFX1NPVVJDRSAgICAgICAgICAgICgxIDw8IDApCj4+ICsjZGVmaW5lIHZfVklERU9f SU5QVVRfRk9STUFUKG4pICAgICAgICAobiA8PCAxKQo+PiArI2RlZmluZSB2X0RFX0VYVEVSTkFM ICAgICAgICAgICAgMQo+PiArI2RlZmluZSB2X0RFX0lOVEVSTkFMICAgICAgICAgICAgMAo+PiAr ZW51bSB7Cj4+ICsgICAgVklERU9fSU5QVVRfU0RSX1JHQjQ0NCA9IDAsCj4+ICsgICAgVklERU9f SU5QVVRfRERSX1JHQjQ0NCA9IDUsCj4+ICsgICAgVklERU9fSU5QVVRfRERSX1lDQkNSNDIyID0g Ngo+PiArfTsKPj4gKwo+PiArI2RlZmluZSBIRE1JX1ZJREVPX0NPTlRSTDIgICAgICAgIDB4MDIK Pj4gKyNkZWZpbmUgbV9WSURFT19PVVRQVVRfQ09MT1IgICAgICAgICgzIDw8IDYpCj4+ICsjZGVm aW5lIG1fVklERU9fSU5QVVRfQklUUyAgICAgICAgKDMgPDwgNCkKPj4gKyNkZWZpbmUgbV9WSURF T19JTlBVVF9DU1AgICAgICAgICgxIDw8IDApCj4+ICsjZGVmaW5lIHZfVklERU9fT1VUUFVUX0NP TE9SKG4pICAgICAgICAoKChuKSAmIDB4MykgPDwgNikKPj4gKyNkZWZpbmUgdl9WSURFT19JTlBV VF9CSVRTKG4pICAgICAgICAobiA8PCA0KQo+PiArI2RlZmluZSB2X1ZJREVPX0lOUFVUX0NTUChu KSAgICAgICAgKG4gPDwgMCkKPj4gK2VudW0gewo+PiArICAgIFZJREVPX0lOUFVUXzEyQklUUyA9 IDAsCj4+ICsgICAgVklERU9fSU5QVVRfMTBCSVRTID0gMSwKPj4gKyAgICBWSURFT19JTlBVVF9S RVZFUlQgPSAyLAo+PiArICAgIFZJREVPX0lOUFVUXzhCSVRTID0gMywKPj4gK307Cj4+ICsKPj4g KyNkZWZpbmUgSERNSV9WSURFT19DT05UUkwgICAgICAgIDB4MDMKPj4gKyNkZWZpbmUgbV9WSURF T19BVVRPX0NTQyAgICAgICAgKDEgPDwgNykKPj4gKyNkZWZpbmUgdl9WSURFT19BVVRPX0NTQyhu KSAgICAgICAgKG4gPDwgNykKPj4gKyNkZWZpbmUgbV9WSURFT19DMF9DMl9TV0FQICAgICAgICAo MSA8PCAwKQo+PiArI2RlZmluZSB2X1ZJREVPX0MwX0MyX1NXQVAobikgICAgICAgIChuIDw8IDAp Cj4+ICtlbnVtIHsKPj4gKyAgICBDMF9DMl9DSEFOR0VfRU5BQkxFID0gMCwKPj4gKyAgICBDMF9D Ml9DSEFOR0VfRElTQUJMRSA9IDEsCj4+ICsgICAgQVVUT19DU0NfRElTQUJMRSA9IDAsCj4+ICsg ICAgQVVUT19DU0NfRU5BQkxFID0gMSwKPj4gK307Cj4+ICsKPj4gKyNkZWZpbmUgSERNSV9WSURF T19DT05UUkwzICAgICAgICAweDA0Cj4+ICsjZGVmaW5lIG1fQ09MT1JfREVQVEhfTk9UX0lORElD QVRFRCAgICAoMSA8PCA0KQo+PiArI2RlZmluZSBtX1NPRiAgICAgICAgICAgICAgICAoMSA8PCAz KQo+PiArI2RlZmluZSBtX0NPTE9SX1JBTkdFICAgICAgICAgICAgKDEgPDwgMikKPj4gKyNkZWZp bmUgbV9DU0MgICAgICAgICAgICAgICAgKDEgPDwgMCkKPj4gKyNkZWZpbmUgdl9DT0xPUl9ERVBU SF9OT1RfSU5ESUNBVEVEKG4pICAgICgobikgPDwgNCkKPj4gKyNkZWZpbmUgdl9TT0ZfRU5BQkxF ICAgICAgICAgICAgKDAgPDwgMykKPj4gKyNkZWZpbmUgdl9TT0ZfRElTQUJMRSAgICAgICAgICAg ICgxIDw8IDMpCj4+ICsjZGVmaW5lIHZfQ09MT1JfUkFOR0VfRlVMTCAgICAgICAgKDEgPDwgMikK Pj4gKyNkZWZpbmUgdl9DT0xPUl9SQU5HRV9MSU1JVEVEICAgICAgICAoMCA8PCAyKQo+PiArI2Rl ZmluZSB2X0NTQ19FTkFCTEUgICAgICAgICAgICAxCj4+ICsjZGVmaW5lIHZfQ1NDX0RJU0FCTEUg ICAgICAgICAgICAwCj4+ICsKPj4gKyNkZWZpbmUgSERNSV9BVl9NVVRFICAgICAgICAgICAgMHgw NQo+PiArI2RlZmluZSBtX0FWTVVURV9DTEVBUiAgICAgICAgICAgICgxIDw8IDcpCj4+ICsjZGVm aW5lIG1fQVZNVVRFX0VOQUJMRSAgICAgICAgICAgICgxIDw8IDYpCj4+ICsjZGVmaW5lIG1fQVVE SU9fTVVURSAgICAgICAgICAgICgxIDw8IDEpCj4+ICsjZGVmaW5lIG1fVklERU9fQkxBQ0sgICAg ICAgICAgICAoMSA8PCAwKQo+PiArI2RlZmluZSB2X0FWTVVURV9DTEVBUihuKSAgICAgICAgKG4g PDwgNykKPj4gKyNkZWZpbmUgdl9BVk1VVEVfRU5BQkxFKG4pICAgICAgICAobiA8PCA2KQo+PiAr I2RlZmluZSB2X0FVRElPX01VVEUobikgICAgICAgICAgICAobiA8PCAxKQo+PiArI2RlZmluZSB2 X1ZJREVPX01VVEUobikgICAgICAgICAgICAobiA8PCAwKQo+PiArCj4+ICsjZGVmaW5lIEhETUlf VklERU9fVElNSU5HX0NUTCAgICAgICAgMHgwOAo+PiArI2RlZmluZSB2X0hTWU5DX1BPTEFSSVRZ KG4pICAgICAgICAobiA8PCAzKQo+PiArI2RlZmluZSB2X1ZTWU5DX1BPTEFSSVRZKG4pICAgICAg ICAobiA8PCAyKQo+PiArI2RlZmluZSB2X0lORVRMQUNFKG4pICAgICAgICAgICAgKG4gPDwgMSkK Pj4gKyNkZWZpbmUgdl9FWFRFUkFOTF9WSURFTyhuKSAgICAgICAgKG4gPDwgMCkKPj4gKwo+PiAr I2RlZmluZSBIRE1JX1ZJREVPX0VYVF9IVE9UQUxfTCAgICAgICAgMHgwOQo+PiArI2RlZmluZSBI RE1JX1ZJREVPX0VYVF9IVE9UQUxfSCAgICAgICAgMHgwYQo+PiArI2RlZmluZSBIRE1JX1ZJREVP X0VYVF9IQkxBTktfTCAgICAgICAgMHgwYgo+PiArI2RlZmluZSBIRE1JX1ZJREVPX0VYVF9IQkxB TktfSCAgICAgICAgMHgwYwo+PiArI2RlZmluZSBIRE1JX1ZJREVPX0VYVF9IREVMQVlfTCAgICAg ICAgMHgwZAo+PiArI2RlZmluZSBIRE1JX1ZJREVPX0VYVF9IREVMQVlfSCAgICAgICAgMHgwZQo+ PiArI2RlZmluZSBIRE1JX1ZJREVPX0VYVF9IRFVSQVRJT05fTCAgICAweDBmCj4+ICsjZGVmaW5l IEhETUlfVklERU9fRVhUX0hEVVJBVElPTl9IICAgIDB4MTAKPj4gKyNkZWZpbmUgSERNSV9WSURF T19FWFRfVlRPVEFMX0wgICAgICAgIDB4MTEKPj4gKyNkZWZpbmUgSERNSV9WSURFT19FWFRfVlRP VEFMX0ggICAgICAgIDB4MTIKPj4gKyNkZWZpbmUgSERNSV9WSURFT19FWFRfVkJMQU5LICAgICAg ICAweDEzCj4+ICsjZGVmaW5lIEhETUlfVklERU9fRVhUX1ZERUxBWSAgICAgICAgMHgxNAo+PiAr I2RlZmluZSBIRE1JX1ZJREVPX0VYVF9WRFVSQVRJT04gICAgMHgxNQo+PiArCj4+ICsjZGVmaW5l IEhETUlfVklERU9fQ1NDX0NPRUYgICAgICAgIDB4MTgKPj4gKwo+PiArI2RlZmluZSBIRE1JX0FV RElPX0NUUkwxICAgICAgICAweDM1Cj4+ICtlbnVtIHsKPj4gKyAgICBDVFNfU09VUkNFX0lOVEVS TkFMID0gMCwKPj4gKyAgICBDVFNfU09VUkNFX0VYVEVSTkFMID0gMSwKPj4gK307Cj4+ICsjZGVm aW5lIHZfQ1RTX1NPVVJDRShuKSAgICAgICAgICAgIChuIDw8IDcpCj4+ICsKPj4gK2VudW0gewo+ PiArICAgIERPV05TQU1QTEVfRElTQUJMRSA9IDAsCj4+ICsgICAgRE9XTlNBTVBMRV8xXzIgPSAx LAo+PiArICAgIERPV05TQU1QTEVfMV80ID0gMiwKPj4gK307Cj4+ICsjZGVmaW5lIHZfRE9XTl9T QU1QTEUobikgICAgICAgIChuIDw8IDUpCj4+ICsKPj4gK2VudW0gewo+PiArICAgIEFVRElPX1NP VVJDRV9JSVMgPSAwLAo+PiArICAgIEFVRElPX1NPVVJDRV9TUERJRiA9IDEsCj4+ICt9Owo+PiAr I2RlZmluZSB2X0FVRElPX1NPVVJDRShuKSAgICAgICAgKG4gPDwgMykKPj4gKwo+PiArI2RlZmlu ZSB2X01DTEtfRU5BQkxFKG4pICAgICAgICAobiA8PCAyKQo+PiArZW51bSB7Cj4+ICsgICAgTUNM S18xMjhGUyA9IDAsCj4+ICsgICAgTUNMS18yNTZGUyA9IDEsCj4+ICsgICAgTUNMS18zODRGUyA9 IDIsCj4+ICsgICAgTUNMS181MTJGUyA9IDMsCj4+ICt9Owo+PiArI2RlZmluZSB2X01DTEtfUkFU SU8obikgICAgICAgICAgICAobikKPj4gKwo+PiArI2RlZmluZSBBVURJT19TQU1QTEVfUkFURSAg ICAgICAgMHgzNwo+PiArZW51bSB7Cj4+ICsgICAgQVVESU9fMzJLID0gMHgzLAo+PiArICAgIEFV RElPXzQ0MUsgPSAweDAsCj4+ICsgICAgQVVESU9fNDhLID0gMHgyLAo+PiArICAgIEFVRElPXzg4 MksgPSAweDgsCj4+ICsgICAgQVVESU9fOTZLID0gMHhhLAo+PiArICAgIEFVRElPXzE3NjRLID0g MHhjLAo+PiArICAgIEFVRElPXzE5MksgPSAweGUsCj4+ICt9Owo+PiArCj4+ICsjZGVmaW5lIEFV RElPX0kyU19NT0RFICAgICAgICAgICAgMHgzOAo+PiArZW51bSB7Cj4+ICsgICAgSTJTX0NIQU5O RUxfMV8yID0gMSwKPj4gKyAgICBJMlNfQ0hBTk5FTF8zXzQgPSAzLAo+PiArICAgIEkyU19DSEFO TkVMXzVfNiA9IDcsCj4+ICsgICAgSTJTX0NIQU5ORUxfN184ID0gMHhmCj4+ICt9Owo+PiArI2Rl ZmluZSB2X0kyU19DSEFOTkVMKG4pICAgICAgICAoKG4pIDw8IDIpCj4+ICtlbnVtIHsKPj4gKyAg ICBJMlNfU1RBTkRBUkQgPSAwLAo+PiArICAgIEkyU19MRUZUX0pVU1RJRklFRCA9IDEsCj4+ICsg ICAgSTJTX1JJR0hUX0pVU1RJRklFRCA9IDIsCj4+ICt9Owo+PiArI2RlZmluZSB2X0kyU19NT0RF KG4pICAgICAgICAgICAgKG4pCj4+ICsKPj4gKyNkZWZpbmUgQVVESU9fSTJTX01BUCAgICAgICAg ICAgIDB4MzkKPj4gKyNkZWZpbmUgQVVESU9fSTJTX1NXQVBTX1NQRElGICAgICAgICAweDNhCj4+ ICsjZGVmaW5lIHZfU1BJREZfRlJFUShuKSAgICAgICAgICAgIChuKQo+PiArCj4+ICsjZGVmaW5l IE5fMzJLICAgICAgICAgICAgICAgIDB4MTAwMAo+PiArI2RlZmluZSBOXzQ0MUsgICAgICAgICAg ICAgICAgMHgxODgwCj4+ICsjZGVmaW5lIE5fODgySyAgICAgICAgICAgICAgICAweDMxMDAKPj4g KyNkZWZpbmUgTl8xNzY0SyAgICAgICAgICAgICAgICAweDYyMDAKPj4gKyNkZWZpbmUgTl80OEsg ICAgICAgICAgICAgICAgMHgxODAwCj4+ICsjZGVmaW5lIE5fOTZLICAgICAgICAgICAgICAgIDB4 MzAwMAo+PiArI2RlZmluZSBOXzE5MksgICAgICAgICAgICAgICAgMHg2MDAwCj4+ICsKPj4gKyNk ZWZpbmUgSERNSV9BVURJT19DSEFOTkVMX1NUQVRVUyAgICAweDNlCj4+ICsjZGVmaW5lIG1fQVVE SU9fU1RBVFVTX05MUENNICAgICAgICAoMSA8PCA3KQo+PiArI2RlZmluZSBtX0FVRElPX1NUQVRV U19VU0UgICAgICAgICgxIDw8IDYpCj4+ICsjZGVmaW5lIG1fQVVESU9fU1RBVFVTX0NPUFlSSUdI VCAgICAoMSA8PCA1KQo+PiArI2RlZmluZSBtX0FVRElPX1NUQVRVU19BRERJVElPTiAgICAgICAg KDMgPDwgMikKPj4gKyNkZWZpbmUgbV9BVURJT19TVEFUVVNfQ0xLX0FDQ1VSQUNZICAgICgyIDw8 IDApCj4+ICsjZGVmaW5lIHZfQVVESU9fU1RBVFVTX05MUENNKG4pICAgICAgICAoKG4gJiAxKSA8 PCA3KQo+PiArI2RlZmluZSBBVURJT19OX0ggICAgICAgICAgICAweDNmCj4+ICsjZGVmaW5lIEFV RElPX05fTSAgICAgICAgICAgIDB4NDAKPj4gKyNkZWZpbmUgQVVESU9fTl9MICAgICAgICAgICAg MHg0MQo+PiArCj4+ICsjZGVmaW5lIEhETUlfQVVESU9fQ1RTX0ggICAgICAgIDB4NDUKPj4gKyNk ZWZpbmUgSERNSV9BVURJT19DVFNfTSAgICAgICAgMHg0Ngo+PiArI2RlZmluZSBIRE1JX0FVRElP X0NUU19MICAgICAgICAweDQ3Cj4+ICsKPj4gKyNkZWZpbmUgSERNSV9ERENfQ0xLX0wgICAgICAg ICAgICAweDRiCj4+ICsjZGVmaW5lIEhETUlfRERDX0NMS19IICAgICAgICAgICAgMHg0Ywo+PiAr Cj4+ICsjZGVmaW5lIEhETUlfRURJRF9TRUdNRU5UX1BPSU5URVIgICAgMHg0ZAo+PiArI2RlZmlu ZSBIRE1JX0VESURfV09SRF9BRERSICAgICAgICAweDRlCj4+ICsjZGVmaW5lIEhETUlfRURJRF9G SUZPX09GRlNFVCAgICAgICAgMHg0Zgo+PiArI2RlZmluZSBIRE1JX0VESURfRklGT19BRERSICAg ICAgICAweDUwCj4+ICsKPj4gKyNkZWZpbmUgSERNSV9QQUNLRVRfU0VORF9NQU5VQUwgICAgICAg IDB4OWMKPj4gKyNkZWZpbmUgSERNSV9QQUNLRVRfU0VORF9BVVRPICAgICAgICAweDlkCj4+ICsj ZGVmaW5lIG1fUEFDS0VUX0dDUF9FTiAgICAgICAgICAgICgxIDw8IDcpCj4+ICsjZGVmaW5lIG1f UEFDS0VUX01TSV9FTiAgICAgICAgICAgICgxIDw8IDYpCj4+ICsjZGVmaW5lIG1fUEFDS0VUX1NE SV9FTiAgICAgICAgICAgICgxIDw8IDUpCj4+ICsjZGVmaW5lIG1fUEFDS0VUX1ZTSV9FTiAgICAg ICAgICAgICgxIDw8IDQpCj4+ICsjZGVmaW5lIHZfUEFDS0VUX0dDUF9FTihuKSAgICAgICAgKChu ICYgMSkgPDwgNykKPj4gKyNkZWZpbmUgdl9QQUNLRVRfTVNJX0VOKG4pICAgICAgICAoKG4gJiAx KSA8PCA2KQo+PiArI2RlZmluZSB2X1BBQ0tFVF9TRElfRU4obikgICAgICAgICgobiAmIDEpIDw8 IDUpCj4+ICsjZGVmaW5lIHZfUEFDS0VUX1ZTSV9FTihuKSAgICAgICAgKChuICYgMSkgPDwgNCkK Pj4gKwo+PiArI2RlZmluZSBIRE1JX0NPTlRST0xfUEFDS0VUX0JVRl9JTkRFWCAgICAweDlmCj4+ ICtlbnVtIHsKPj4gKyAgICBJTkZPRlJBTUVfVlNJID0gMHgwNSwKPj4gKyAgICBJTkZPRlJBTUVf QVZJID0gMHgwNiwKPj4gKyAgICBJTkZPRlJBTUVfQUFJID0gMHgwOCwKPj4gK307Cj4+ICsKPj4g KyNkZWZpbmUgSERNSV9DT05UUk9MX1BBQ0tFVF9BRERSICAgIDB4YTAKPj4gKyNkZWZpbmUgSERN SV9TSVpFX1ZTSV9JTkZPRlJBTUUgICAgICAgIDB4MEEKPj4gKyNkZWZpbmUgSERNSV9TSVpFX0FW SV9JTkZPRlJBTUUgICAgICAgIDB4MTEKPj4gKyNkZWZpbmUgSERNSV9TSVpFX0FVRElPX0lORk9G UkFNRSAgICAweDBGCj4+ICtlbnVtIHsKPj4gKyAgICBBVklfQ09MT1JfTU9ERV9SR0IgPSAwLAo+ PiArICAgIEFWSV9DT0xPUl9NT0RFX1lDQkNSNDIyID0gMSwKPj4gKyAgICBBVklfQ09MT1JfTU9E RV9ZQ0JDUjQ0NCA9IDIsCj4+ICsgICAgQVZJX0NPTE9SSU1FVFJZX05PX0RBVEEgPSAwLAo+PiAr Cj4+ICsgICAgQVZJX0NPTE9SSU1FVFJZX1NNUFRFXzE3ME0gPSAxLAo+PiArICAgIEFWSV9DT0xP UklNRVRSWV9JVFU3MDkgPSAyLAo+PiArICAgIEFWSV9DT0xPUklNRVRSWV9FWFRFTkRFRCA9IDMs Cj4+ICsKPj4gKyAgICBBVklfQ09ERURfRlJBTUVfQVNQRUNUX05PX0RBVEEgPSAwLAo+PiArICAg IEFWSV9DT0RFRF9GUkFNRV9BU1BFQ1RfNF8zID0gMSwKPj4gKyAgICBBVklfQ09ERURfRlJBTUVf QVNQRUNUXzE2XzkgPSAyLAo+PiArCj4+ICsgICAgQUNUSVZFX0FTUEVDVF9SQVRFX1NBTUVfQVNf Q09ERURfRlJBTUUgPSAweDA4LAo+PiArICAgIEFDVElWRV9BU1BFQ1RfUkFURV80XzMgPSAweDA5 LAo+PiArICAgIEFDVElWRV9BU1BFQ1RfUkFURV8xNl85ID0gMHgwQSwKPj4gKyAgICBBQ1RJVkVf QVNQRUNUX1JBVEVfMTRfOSA9IDB4MEIsCj4+ICt9Owo+PiArCj4+ICsjZGVmaW5lIEhETUlfSERD UF9DVFJMICAgICAgICAgICAgMHg1Mgo+PiArI2RlZmluZSBtX0hETUlfRFZJICAgICAgICAgICAg KDEgPDwgMSkKPj4gKyNkZWZpbmUgdl9IRE1JX0RWSShuKSAgICAgICAgICAgIChuIDw8IDEpCj4+ ICsKPj4gKyNkZWZpbmUgSERNSV9JTlRFUlJVUFRfTUFTSzEgICAgICAgIDB4YzAKPj4gKyNkZWZp bmUgSERNSV9JTlRFUlJVUFRfU1RBVFVTMSAgICAgICAgMHhjMQo+PiArI2RlZmluZSAgICBtX0lO VF9BQ1RJVkVfVlNZTkMgICAgICAgICgxIDw8IDUpCj4+ICsjZGVmaW5lIG1fSU5UX0VESURfUkVB RFkgICAgICAgICgxIDw8IDIpCj4+ICsKPj4gKyNkZWZpbmUgSERNSV9JTlRFUlJVUFRfTUFTSzIg ICAgICAgIDB4YzIKPj4gKyNkZWZpbmUgSERNSV9JTlRFUlJVUFRfU1RBVFVTMiAgICAgICAgMHhj Mwo+PiArI2RlZmluZSBtX0lOVF9IRENQX0VSUiAgICAgICAgICAgICgxIDw8IDcpCj4+ICsjZGVm aW5lIG1fSU5UX0JLU1ZfRkxBRyAgICAgICAgICAgICgxIDw8IDYpCj4+ICsjZGVmaW5lIG1fSU5U X0hEQ1BfT0sgICAgICAgICAgICAoMSA8PCA0KQo+PiArCj4+ICsjZGVmaW5lIEhETUlfU1RBVFVT ICAgICAgICAgICAgMHhjOAo+PiArI2RlZmluZSBtX0hPVFBMVUcgICAgICAgICAgICAoMSA8PCA3 KQo+PiArI2RlZmluZSBtX01BU0tfSU5UX0hPVFBMVUcgICAgICAgICgxIDw8IDUpCj4+ICsjZGVm aW5lIG1fSU5UX0hPVFBMVUcgICAgICAgICAgICAoMSA8PCAxKQo+PiArI2RlZmluZSB2X01BU0tf SU5UX0hPVFBMVUcobikgICAgICAgICgobiAmIDB4MSkgPDwgNSkKPj4gKwo+PiArI2RlZmluZSBI RE1JX0NPTE9SQkFSICAgICAgICAgICAgICAgICAgIDB4YzkKPj4gKwo+PiArI2RlZmluZSBIRE1J X1BIWV9TWU5DICAgICAgICAgICAgMHhjZQo+PiArI2RlZmluZSBIRE1JX1BIWV9TWVNfQ1RMICAg ICAgICAweGUwCj4+ICsjZGVmaW5lIG1fVE1EU19DTEtfU09VUkNFICAgICAgICAoMSA8PCA1KQo+ PiArI2RlZmluZSB2X1RNRFNfRlJPTV9QTEwgICAgICAgICAgICAoMCA8PCA1KQo+PiArI2RlZmlu ZSB2X1RNRFNfRlJPTV9HRU4gICAgICAgICAgICAoMSA8PCA1KQo+PiArI2RlZmluZSBtX1BIQVNF X0NMSyAgICAgICAgICAgICgxIDw8IDQpCj4+ICsjZGVmaW5lIHZfREVGQVVMVF9QSEFTRSAgICAg ICAgICAgICgwIDw8IDQpCj4+ICsjZGVmaW5lIHZfU1lOQ19QSEFTRSAgICAgICAgICAgICgxIDw8 IDQpCj4+ICsjZGVmaW5lIG1fVE1EU19DVVJSRU5UX1BXUiAgICAgICAgKDEgPDwgMykKPj4gKyNk ZWZpbmUgdl9UVVJOX09OX0NVUlJFTlQgICAgICAgICgwIDw8IDMpCj4+ICsjZGVmaW5lIHZfQ0FU X09GRl9DVVJSRU5UICAgICAgICAoMSA8PCAzKQo+PiArI2RlZmluZSBtX0JBTkRHQVBfUFdSICAg ICAgICAgICAgKDEgPDwgMikKPj4gKyNkZWZpbmUgdl9CQU5ER0FQX1BXUl9VUCAgICAgICAgKDAg PDwgMikKPj4gKyNkZWZpbmUgdl9CQU5ER0FQX1BXUl9ET1dOICAgICAgICAoMSA8PCAyKQo+PiAr I2RlZmluZSBtX1BMTF9QV1IgICAgICAgICAgICAoMSA8PCAxKQo+PiArI2RlZmluZSB2X1BMTF9Q V1JfVVAgICAgICAgICAgICAoMCA8PCAxKQo+PiArI2RlZmluZSB2X1BMTF9QV1JfRE9XTiAgICAg ICAgICAgICgxIDw8IDEpCj4+ICsjZGVmaW5lIG1fVE1EU19DSEdfUFdSICAgICAgICAgICAgKDEg PDwgMCkKPj4gKyNkZWZpbmUgdl9UTURTX0NIR19QV1JfVVAgICAgICAgICgwIDw8IDApCj4+ICsj ZGVmaW5lIHZfVE1EU19DSEdfUFdSX0RPV04gICAgICAgICgxIDw8IDApCj4+ICsKPj4gKyNkZWZp bmUgSERNSV9QSFlfQ0hHX1BXUiAgICAgICAgMHhlMQo+PiArI2RlZmluZSB2X0NMS19DSEdfUFdS KG4pICAgICAgICAoKG4gJiAxKSA8PCAzKQo+PiArI2RlZmluZSB2X0RBVEFfQ0hHX1BXUihuKSAg ICAgICAgKChuICYgNykgPDwgMCkKPj4gKwo+PiArI2RlZmluZSBIRE1JX1BIWV9EUklWRVIgICAg ICAgICAgICAweGUyCj4+ICsjZGVmaW5lIHZfQ0xLX01BSU5fRFJJVkVSKG4pICAgICAgICAobiA8 PCA0KQo+PiArI2RlZmluZSB2X0RBVEFfTUFJTl9EUklWRVIobikgICAgICAgIChuIDw8IDApCj4+ ICsKPj4gKyNkZWZpbmUgSERNSV9QSFlfUFJFX0VNUEhBU0lTICAgICAgICAweGUzCj4+ICsjZGVm aW5lIHZfUFJFX0VNUEhBU0lTKG4pICAgICAgICAoKG4gJiA3KSA8PCA0KQo+PiArI2RlZmluZSB2 X0NMS19QUkVfRFJJVkVSKG4pICAgICAgICAoKG4gJiAzKSA8PCAyKQo+PiArI2RlZmluZSB2X0RB VEFfUFJFX0RSSVZFUihuKSAgICAgICAgKChuICYgMykgPDwgMCkKPj4gKwo+PiArI2RlZmluZSBI RE1JX1BIWV9GRUVEQkFDS19ESVZfUkFUSU9fTE9XICAgICAgICAweGU3Cj4+ICsjZGVmaW5lIHZf RkVFREJBQ0tfRElWX0xPVyhuKSAgICAgICAgICAgIChuICYgMHhmZikKPj4gKyNkZWZpbmUgSERN SV9QSFlfRkVFREJBQ0tfRElWX1JBVElPX0hJR0ggICAgMHhlOAo+PiArI2RlZmluZSB2X0ZFRURC QUNLX0RJVl9ISUdIKG4pICAgICAgICAgICAgKG4gJiAxKQo+PiArCj4+ICsjZGVmaW5lIEhETUlf UEhZX1BSRV9ESVZfUkFUSU8gICAgICAgIDB4ZWQKPj4gKyNkZWZpbmUgdl9QUkVfRElWX1JBVElP KG4pICAgICAgICAobiAmIDB4MWYpCj4+ICsKPj4gKyNkZWZpbmUgSERNSV9DRUNfQ1RSTCAgICAg ICAgICAgIDB4ZDAKPj4gKyNkZWZpbmUgbV9BREpVU1RfRk9SX0hJU0VOU0UgICAgICAgICgxIDw8 IDYpCj4+ICsjZGVmaW5lIG1fUkVKRUNUX1JYX0JST0FEQ0FTVCAgICAgICAgKDEgPDwgNSkKPj4g KyNkZWZpbmUgbV9CVVNGUkVFVElNRV9FTkFCTEUgICAgICAgICgxIDw8IDIpCj4+ICsjZGVmaW5l IG1fUkVKRUNUX1JYICAgICAgICAgICAgKDEgPDwgMSkKPj4gKyNkZWZpbmUgbV9TVEFSVF9UWCAg ICAgICAgICAgICgxIDw8IDApCj4+ICsKPj4gKyNkZWZpbmUgSERNSV9DRUNfREFUQSAgICAgICAg ICAgIDB4ZDEKPj4gKyNkZWZpbmUgSERNSV9DRUNfVFhfT0ZGU0VUICAgICAgICAweGQyCj4+ICsj ZGVmaW5lIEhETUlfQ0VDX1JYX09GRlNFVCAgICAgICAgMHhkMwo+PiArI2RlZmluZSBIRE1JX0NF Q19DTEtfSCAgICAgICAgICAgIDB4ZDQKPj4gKyNkZWZpbmUgSERNSV9DRUNfQ0xLX0wgICAgICAg ICAgICAweGQ1Cj4+ICsjZGVmaW5lIEhETUlfQ0VDX1RYX0xFTkdUSCAgICAgICAgMHhkNgo+PiAr I2RlZmluZSBIRE1JX0NFQ19SWF9MRU5HVEggICAgICAgIDB4ZDcKPj4gKyNkZWZpbmUgSERNSV9D RUNfVFhfSU5UX01BU0sgICAgICAgIDB4ZDgKPj4gKyNkZWZpbmUgbV9UWF9ET05FICAgICAgICAg ICAgKDEgPDwgMykKPj4gKyNkZWZpbmUgbV9UWF9OT0FDSyAgICAgICAgICAgICgxIDw8IDIpCj4+ ICsjZGVmaW5lIG1fVFhfQlJPQURDQVNUX1JFSiAgICAgICAgKDEgPDwgMSkKPj4gKyNkZWZpbmUg bV9UWF9CVVNOT1RGUkVFICAgICAgICAgICAgKDEgPDwgMCkKPj4gKwo+PiArI2RlZmluZSBIRE1J X0NFQ19SWF9JTlRfTUFTSyAgICAgICAgMHhkOQo+PiArI2RlZmluZSBtX1JYX0xBX0VSUiAgICAg ICAgICAgICgxIDw8IDQpCj4+ICsjZGVmaW5lIG1fUlhfR0xJVENIICAgICAgICAgICAgKDEgPDwg MykKPj4gKyNkZWZpbmUgbV9SWF9ET05FICAgICAgICAgICAgKDEgPDwgMCkKPj4gKwo+PiArI2Rl ZmluZSBIRE1JX0NFQ19UWF9JTlQgICAgICAgICAgICAweGRhCj4+ICsjZGVmaW5lIEhETUlfQ0VD X1JYX0lOVCAgICAgICAgICAgIDB4ZGIKPj4gKyNkZWZpbmUgSERNSV9DRUNfQlVTRlJFRVRJTUVf TCAgICAgICAgMHhkYwo+PiArI2RlZmluZSBIRE1JX0NFQ19CVVNGUkVFVElNRV9IICAgICAgICAw eGRkCj4+ICsjZGVmaW5lIEhETUlfQ0VDX0xPR0lDQUREUiAgICAgICAgMHhkZQo+PiArCj4+ICsj ZW5kaWYgLyogX19JTk5PX0hETUlfSF9fICovCj4KPgoKCi0tIApUaGFua3MsCkNhZXNhcgoKCl9f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkxpbnV4LXJvY2tj aGlwIG1haWxpbmcgbGlzdApMaW51eC1yb2NrY2hpcEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6 Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcm9ja2NoaXAK From mboxrd@z Thu Jan 1 00:00:00 1970 From: caesar.upstream@gmail.com (Caesar Wang) Date: Sun, 24 Jan 2016 15:34:07 +0800 Subject: [PATCH v3 1/2] drm: rockchip/hdmi: add Innosilicon HDMI support In-Reply-To: <569C3E36.10103@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> Message-ID: <56A47E6F.8050104@gmail.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org 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. >> 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__ */ > > -- Thanks, Caesar From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751184AbcAXHeT (ORCPT ); Sun, 24 Jan 2016 02:34:19 -0500 Received: from mail-pa0-f48.google.com ([209.85.220.48]:35635 "EHLO mail-pa0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750786AbcAXHeO (ORCPT ); Sun, 24 Jan 2016 02:34:14 -0500 Subject: Re: [PATCH v3 1/2] drm: rockchip/hdmi: add Innosilicon HDMI support To: Yakir Yang 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> 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: Caesar Wang Message-ID: <56A47E6F.8050104@gmail.com> Date: Sun, 24 Jan 2016 15:34:07 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 In-Reply-To: <569C3E36.10103@rock-chips.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. >> 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__ */ > > -- Thanks, Caesar