From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3C752C001DF for ; Mon, 24 Jul 2023 10:51:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=vjGH7lfbgk7/JUsd0e1yLn91Sfwr6zybFX/J0QikYQk=; b=z02JRk29aPNvYg +tZalikMnt837Q3vD1wLi0be1VlFE42MnGReFIZgBbQcH3k7skgbG5cAU7MU+mGccNpAXW7f8jt/g 7Nx7FphcFvKUDWp+SOuteQ30YZcJV//I3gejygpKmXaxZxV2sCT7fPd7P0wzatpFn8d+2cqB/eIib y7aOIbToAjhnT1MEMV5GWaMXRRg0jvSeY/0m/z9s4KAj9g1S8LT4DkFnn8FS3GNvoGi0Fty+rqp68 cCS0ZX9CWGxTzqq5BwnXT5eV0DjiByYHOekZCcAQV1FZrbZcCSjr+vIdbPn4GZDxcABcW3PS91kQe qJ54Yvk1DM9v83U2XxMg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qNtAS-003tgU-2j; Mon, 24 Jul 2023 10:51:56 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qNtAN-003teg-36; Mon, 24 Jul 2023 10:51:55 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 13E276103C; Mon, 24 Jul 2023 10:51:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C40AC433C7; Mon, 24 Jul 2023 10:51:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690195910; bh=Hm4KpRgolrbkVpbCQNLJbZKNI2aGi1klArYlS2xQMGM=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=dU8zYDo5/5EjJOeprdTvhp9BX+oIjNaKE4W+cYWvjy7w2i1Ufqbg+q58mQ6Zakowq sYA0K5Jtn0l7k/RKfSt+IIhdw9weUbjGdkYa7XeHQ3ZozEaUzvJb/dmGu1EcdUD91y 92vTj/gJyZImKETv1DlDpmgsb2GvyceIpNOA2dPQxuIk83Q+o6HYcfjqLJarNxbNZD d5YeZHkTHIyfaGUP9dPvkikLFWXe2pbydbf9grdJvggd/7J6lu7nQ1Nu7HIKDs1ZNw X7ooUtyvsZbQ6s9rJROEoFPQPbPUBNXLGbfdhBc8akMNGjezhTDym2huLL7PBcCx9c z7pkm7C2RszZw== Date: Mon, 24 Jul 2023 16:21:45 +0530 From: Vinod Koul To: Sandor Yu Cc: andrzej.hajda@intel.com, neil.armstrong@linaro.org, Laurent.pinchart@ideasonboard.com, jonas@kwiboo.se, jernej.skrabec@gmail.com, airlied@gmail.com, daniel@ffwll.ch, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com, dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, kernel@pengutronix.de, linux-imx@nxp.com, oliver.brown@nxp.com, alexander.stein@ew.tq-group.com, sam@ravnborg.org Subject: Re: [PATCH v7 6/7] phy: freescale: Add DisplayPort PHY driver for i.MX8MQ Message-ID: References: <50f342972001f079a0946f7718c6e3fa6aed9503.1689580812.git.Sandor.yu@nxp.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <50f342972001f079a0946f7718c6e3fa6aed9503.1689580812.git.Sandor.yu@nxp.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230724_035152_151778_D91BE551 X-CRM114-Status: GOOD ( 28.92 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org T24gMTctMDctMjMsIDE2OjAzLCBTYW5kb3IgWXUgd3JvdGU6Cj4gQWRkIENhZGVuY2UgSERQLVRY IERpc3BsYXlQb3J0IFBIWSBkcml2ZXIgZm9yIGkuTVg4TVEKPiAKPiBDYWRlbmNlIEhEUC1UWCBQ SFkgY291bGQgYmUgcHV0IGluIGVpdGhlciBEUCBtb2RlIG9yCj4gSERNSSBtb2RlIGJhc2Ugb24g dGhlIGNvbmZpZ3VyYXRpb24gY2hvc2VuLgo+IERpc3BsYXlQb3J0IFBIWSBtb2RlIGlzIGNvbmZp Z3VyYXRlZCBpbiB0aGUgZHJpdmVyLgo+IAo+IFNpZ25lZC1vZmYtYnk6IFNhbmRvciBZdSA8U2Fu ZG9yLnl1QG54cC5jb20+Cj4gLS0tCj4gIGRyaXZlcnMvcGh5L2ZyZWVzY2FsZS9LY29uZmlnICAg ICAgICAgICAgIHwgICA5ICsKPiAgZHJpdmVycy9waHkvZnJlZXNjYWxlL01ha2VmaWxlICAgICAg ICAgICAgfCAgIDEgKwo+ICBkcml2ZXJzL3BoeS9mcmVlc2NhbGUvcGh5LWZzbC1pbXg4bXEtZHAu YyB8IDY5OCArKysrKysrKysrKysrKysrKysrKysrCj4gIDMgZmlsZXMgY2hhbmdlZCwgNzA4IGlu c2VydGlvbnMoKykKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvcGh5L2ZyZWVzY2FsZS9w aHktZnNsLWlteDhtcS1kcC5jCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGh5L2ZyZWVzY2Fs ZS9LY29uZmlnIGIvZHJpdmVycy9waHkvZnJlZXNjYWxlL0tjb25maWcKPiBpbmRleCA4NTM5NThm YjJjMDYuLjI5OTliYTFlNTdkMCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3BoeS9mcmVlc2NhbGUv S2NvbmZpZwo+ICsrKyBiL2RyaXZlcnMvcGh5L2ZyZWVzY2FsZS9LY29uZmlnCj4gQEAgLTM1LDYg KzM1LDE1IEBAIGNvbmZpZyBQSFlfRlNMX0lNWDhNX1BDSUUKPiAgCSAgRW5hYmxlIHRoaXMgdG8g YWRkIHN1cHBvcnQgZm9yIHRoZSBQQ0lFIFBIWSBhcyBmb3VuZCBvbgo+ICAJICBpLk1YOE0gZmFt aWx5IG9mIFNPQ3MuCj4gIAo+ICtjb25maWcgUEhZX0ZTTF9JTVg4TVFfRFBfUEhZCj4gKwl0cmlz dGF0ZSAiRnJlZXNjYWxlIGkuTVg4TVEgRFAgUEhZIHN1cHBvcnQiCj4gKwlkZXBlbmRzIG9uIE9G ICYmIEhBU19JT01FTQo+ICsJZGVwZW5kcyBvbiBDT01NT05fQ0xLCj4gKwlzZWxlY3QgR0VORVJJ Q19QSFkKPiArCWhlbHAKPiArCSAgRW5hYmxlIHRoaXMgdG8gc3VwcG9ydCB0aGUgQ2FkZW5jZSBI RFBUWCBEUCBQSFkgZHJpdmVyCj4gKwkgIG9uIGkuTVg4TVEgU09DLgo+ICsKPiAgZW5kaWYKPiAg Cj4gIGNvbmZpZyBQSFlfRlNMX0xZTlhfMjhHCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGh5L2Zy ZWVzY2FsZS9NYWtlZmlsZSBiL2RyaXZlcnMvcGh5L2ZyZWVzY2FsZS9NYWtlZmlsZQo+IGluZGV4 IGNlZGIzMjhiYzRkMi4uOTE1YTQyOWQ5ZmJjIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvcGh5L2Zy ZWVzY2FsZS9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvcGh5L2ZyZWVzY2FsZS9NYWtlZmlsZQo+ IEBAIC00LDMgKzQsNCBAQCBvYmotJChDT05GSUdfUEhZX01JWEVMX0xWRFNfUEhZKQkrPSBwaHkt ZnNsLWlteDhxbS1sdmRzLXBoeS5vCj4gIG9iai0kKENPTkZJR19QSFlfTUlYRUxfTUlQSV9EUEhZ KQkrPSBwaHktZnNsLWlteDgtbWlwaS1kcGh5Lm8KPiAgb2JqLSQoQ09ORklHX1BIWV9GU0xfSU1Y OE1fUENJRSkJKz0gcGh5LWZzbC1pbXg4bS1wY2llLm8KPiAgb2JqLSQoQ09ORklHX1BIWV9GU0xf TFlOWF8yOEcpCQkrPSBwaHktZnNsLWx5bngtMjhnLm8KPiArb2JqLSQoQ09ORklHX1BIWV9GU0xf SU1YOE1RX0RQX1BIWSkJKz0gcGh5LWZzbC1pbXg4bXEtZHAubwo+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL3BoeS9mcmVlc2NhbGUvcGh5LWZzbC1pbXg4bXEtZHAuYyBiL2RyaXZlcnMvcGh5L2ZyZWVz Y2FsZS9waHktZnNsLWlteDhtcS1kcC5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAw MDAwMDAwMDAwMDAuLjQxNTI3M2FjNmFhNQo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJz L3BoeS9mcmVlc2NhbGUvcGh5LWZzbC1pbXg4bXEtZHAuYwo+IEBAIC0wLDAgKzEsNjk4IEBACj4g Ky8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkKPiArLyoKPiArICogQ2Fk ZW5jZSBIRFAtVFggRGlzcGxheSBQb3J0IEludGVyZmFjZSAoRFApIFBIWSBkcml2ZXIKPiArICoK PiArICogQ29weXJpZ2h0IChDKSAyMDIyIE5YUCBTZW1pY29uZHVjdG9yLCBJbmMuCj4gKyAqLwo+ ICsjaW5jbHVkZSA8YXNtL3VuYWxpZ25lZC5oPgo+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4g KyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3BoeS9waHkuaD4K PiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgv aW8uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2lvcG9sbC5oPgo+ICsKPiArI2luY2x1ZGUgPGRybS9i cmlkZ2UvY2Rucy1taGRwLW1haWxib3guaD4KPiArCj4gKyNkZWZpbmUgQUREUl9QSFlfQUZFCTB4 ODAwMDAKPiArCj4gKy8qIFBIWSByZWdpc3RlcnMgKi8KPiArI2RlZmluZSBDTU5fU1NNX0JJQVNf VE1SICAgICAgICAgICAgICAgIDB4MDAyMgo+ICsjZGVmaW5lIENNTl9QTExTTTBfUExMRU5fVE1S ICAgICAgICAgICAgMHgwMDI5Cj4gKyNkZWZpbmUgQ01OX1BMTFNNMF9QTExQUkVfVE1SICAgICAg ICAgICAweDAwMmEKPiArI2RlZmluZSBDTU5fUExMU00wX1BMTFZSRUZfVE1SICAgICAgICAgIDB4 MDAyYgo+ICsjZGVmaW5lIENNTl9QTExTTTBfUExMTE9DS19UTVIgICAgICAgICAgMHgwMDJjCj4g KyNkZWZpbmUgQ01OX1BMTFNNMF9VU0VSX0RFRl9DVFJMICAgICAgICAweDAwMmYKPiArI2RlZmlu ZSBDTU5fUFNNX0NMS19DVFJMICAgICAgICAgICAgICAgIDB4MDA2MQo+ICsjZGVmaW5lIENNTl9Q TEwwX1ZDT0NBTF9TVEFSVCAgICAgICAgICAgMHgwMDgxCj4gKyNkZWZpbmUgQ01OX1BMTDBfVkNP Q0FMX0lOSVRfVE1SICAgICAgICAweDAwODQKPiArI2RlZmluZSBDTU5fUExMMF9WQ09DQUxfSVRF Ul9UTVIgICAgICAgIDB4MDA4NQo+ICsjZGVmaW5lIENNTl9QTEwwX0lOVERJViAgICAgICAgICAg ICAgICAgMHgwMDk0Cj4gKyNkZWZpbmUgQ01OX1BMTDBfRlJBQ0RJViAgICAgICAgICAgICAgICAw eDAwOTUKPiArI2RlZmluZSBDTU5fUExMMF9ISUdIX1RIUiAgICAgICAgICAgICAgIDB4MDA5Ngo+ ICsjZGVmaW5lIENNTl9QTEwwX0RTTV9ESUFHICAgICAgICAgICAgICAgMHgwMDk3Cj4gKyNkZWZp bmUgQ01OX1BMTDBfU1NfQ1RSTDIgICAgICAgICAgICAgICAweDAwOTkKPiArI2RlZmluZSBDTU5f SUNBTF9JTklUX1RNUiAgICAgICAgICAgICAgIDB4MDBjNAo+ICsjZGVmaW5lIENNTl9JQ0FMX0lU RVJfVE1SICAgICAgICAgICAgICAgMHgwMGM1Cj4gKyNkZWZpbmUgQ01OX1JYQ0FMX0lOSVRfVE1S ICAgICAgICAgICAgICAweDAwZDQKPiArI2RlZmluZSBDTU5fUlhDQUxfSVRFUl9UTVIgICAgICAg ICAgICAgIDB4MDBkNQo+ICsjZGVmaW5lIENNTl9UWFBVQ0FMX0lOSVRfVE1SICAgICAgICAgICAg MHgwMGU0Cj4gKyNkZWZpbmUgQ01OX1RYUFVDQUxfSVRFUl9UTVIgICAgICAgICAgICAweDAwZTUK PiArI2RlZmluZSBDTU5fVFhQRENBTF9JTklUX1RNUiAgICAgICAgICAgIDB4MDBmNAo+ICsjZGVm aW5lIENNTl9UWFBEQ0FMX0lURVJfVE1SICAgICAgICAgICAgMHgwMGY1Cj4gKyNkZWZpbmUgQ01O X0lDQUxfQURKX0lOSVRfVE1SICAgICAgICAgICAweDAxMDIKPiArI2RlZmluZSBDTU5fSUNBTF9B REpfSVRFUl9UTVIgICAgICAgICAgIDB4MDEwMwo+ICsjZGVmaW5lIENNTl9SWF9BREpfSU5JVF9U TVIgICAgICAgICAgICAgMHgwMTA2Cj4gKyNkZWZpbmUgQ01OX1JYX0FESl9JVEVSX1RNUiAgICAg ICAgICAgICAweDAxMDcKPiArI2RlZmluZSBDTU5fVFhQVV9BREpfSU5JVF9UTVIgICAgICAgICAg IDB4MDEwYQo+ICsjZGVmaW5lIENNTl9UWFBVX0FESl9JVEVSX1RNUiAgICAgICAgICAgMHgwMTBi Cj4gKyNkZWZpbmUgQ01OX1RYUERfQURKX0lOSVRfVE1SICAgICAgICAgICAweDAxMGUKPiArI2Rl ZmluZSBDTU5fVFhQRF9BREpfSVRFUl9UTVIgICAgICAgICAgIDB4MDEwZgo+ICsjZGVmaW5lIENN Tl9ESUFHX1BMTDBfRkJIX09WUkQgICAgICAgICAgMHgwMWMwCj4gKyNkZWZpbmUgQ01OX0RJQUdf UExMMF9GQkxfT1ZSRCAgICAgICAgICAweDAxYzEKPiArI2RlZmluZSBDTU5fRElBR19QTEwwX09W UkQgICAgICAgICAgICAgIDB4MDFjMgo+ICsjZGVmaW5lIENNTl9ESUFHX1BMTDBfVEVTVF9NT0RF ICAgICAgICAgMHgwMWM0Cj4gKyNkZWZpbmUgQ01OX0RJQUdfUExMMF9WMklfVFVORSAgICAgICAg ICAweDAxYzUKPiArI2RlZmluZSBDTU5fRElBR19QTEwwX0NQX1RVTkUgICAgICAgICAgIDB4MDFj Ngo+ICsjZGVmaW5lIENNTl9ESUFHX1BMTDBfTEZfUFJPRyAgICAgICAgICAgMHgwMWM3Cj4gKyNk ZWZpbmUgQ01OX0RJQUdfUExMMF9QVEFUSVNfVFVORTEgICAgICAweDAxYzgKPiArI2RlZmluZSBD TU5fRElBR19QTEwwX1BUQVRJU19UVU5FMiAgICAgIDB4MDFjOQo+ICsjZGVmaW5lIENNTl9ESUFH X0hTQ0xLX1NFTCAgICAgICAgICAgICAgMHgwMWUwCj4gKyNkZWZpbmUgQ01OX0RJQUdfUEVSX0NB TF9BREogICAgICAgICAgICAweDAxZWMKPiArI2RlZmluZSBDTU5fRElBR19DQUxfQ1RSTCAgICAg ICAgICAgICAgIDB4MDFlZAo+ICsjZGVmaW5lIENNTl9ESUFHX0FDWUEgICAgICAgICAgICAgICAg ICAgMHgwMWZmCj4gKyNkZWZpbmUgWENWUl9QU01fUkNUUkwgICAgICAgICAgICAgICAgICAweDQw MDEKPiArI2RlZmluZSBYQ1ZSX1BTTV9DQUxfVE1SICAgICAgICAgICAgICAgIDB4NDAwMgo+ICsj ZGVmaW5lIFhDVlJfUFNNX0EwSU5fVE1SICAgICAgICAgICAgICAgMHg0MDAzCj4gKyNkZWZpbmUg VFhfVFhDQ19DQUxfU0NMUl9NVUxUXzAgICAgICAgICAweDQwNDcKPiArI2RlZmluZSBUWF9UWEND X0NQT1NUX01VTFRfMDBfMCAgICAgICAgIDB4NDA0Ywo+ICsjZGVmaW5lIFhDVlJfRElBR19QTExE UkNfQ1RSTCAgICAgICAgICAgMHg0MGUwCj4gKyNkZWZpbmUgWENWUl9ESUFHX1BMTERSQ19DVFJM ICAgICAgICAgICAweDQwZTAKPiArI2RlZmluZSBYQ1ZSX0RJQUdfSFNDTEtfU0VMICAgICAgICAg ICAgIDB4NDBlMQo+ICsjZGVmaW5lIFhDVlJfRElBR19MQU5FX0ZDTV9FTl9NR05fVE1SICAgMHg0 MGYyCj4gKyNkZWZpbmUgVFhfUFNDX0EwICAgICAgICAgICAgICAgICAgICAgICAweDQxMDAKPiAr I2RlZmluZSBUWF9QU0NfQTEgICAgICAgICAgICAgICAgICAgICAgIDB4NDEwMQo+ICsjZGVmaW5l IFRYX1BTQ19BMiAgICAgICAgICAgICAgICAgICAgICAgMHg0MTAyCj4gKyNkZWZpbmUgVFhfUFND X0EzICAgICAgICAgICAgICAgICAgICAgICAweDQxMDMKPiArI2RlZmluZSBUWF9SQ1ZERVRfRU5f VE1SICAgICAgICAgICAgICAgIDB4NDEyMgo+ICsjZGVmaW5lIFRYX1JDVkRFVF9TVF9UTVIgICAg ICAgICAgICAgICAgMHg0MTIzCj4gKyNkZWZpbmUgVFhfRElBR19CR1JFRl9QUkVEUlZfREVMQVkg ICAgICAweDQxZTcKPiArI2RlZmluZSBUWF9ESUFHX0JHUkVGX1BSRURSVl9ERUxBWSAgICAgIDB4 NDFlNwo+ICsjZGVmaW5lIFRYX0RJQUdfQUNZQV8wICAgICAgICAgICAgICAgICAgMHg0MWZmCj4g KyNkZWZpbmUgVFhfRElBR19BQ1lBXzEgICAgICAgICAgICAgICAgICAweDQzZmYKPiArI2RlZmlu ZSBUWF9ESUFHX0FDWUFfMiAgICAgICAgICAgICAgICAgIDB4NDVmZgo+ICsjZGVmaW5lIFRYX0RJ QUdfQUNZQV8zICAgICAgICAgICAgICAgICAgMHg0N2ZmCj4gKyNkZWZpbmUgVFhfQU5BX0NUUkxf UkVHXzEgICAgICAgICAgICAgICAweDUwMjAKPiArI2RlZmluZSBUWF9BTkFfQ1RSTF9SRUdfMiAg ICAgICAgICAgICAgIDB4NTAyMQo+ICsjZGVmaW5lIFRYX0RJR19DVFJMX1JFR18xICAgICAgICAg ICAgICAgMHg1MDIzCj4gKyNkZWZpbmUgVFhfRElHX0NUUkxfUkVHXzIgICAgICAgICAgICAgICAw eDUwMjQKPiArI2RlZmluZSBUWERBX0NZQV9BVVhEQV9DWUEgICAgICAgICAgICAgIDB4NTAyNQo+ ICsjZGVmaW5lIFRYX0FOQV9DVFJMX1JFR18zICAgICAgICAgICAgICAgMHg1MDI2Cj4gKyNkZWZp bmUgVFhfQU5BX0NUUkxfUkVHXzQgICAgICAgICAgICAgICAweDUwMjcKPiArI2RlZmluZSBUWF9B TkFfQ1RSTF9SRUdfNSAgICAgICAgICAgICAgIDB4NTAyOQo+ICsjZGVmaW5lIFJYX1BTQ19BMCAg ICAgICAgICAgICAgICAgICAgICAgMHg4MDAwCj4gKyNkZWZpbmUgUlhfUFNDX0NBTCAgICAgICAg ICAgICAgICAgICAgICAweDgwMDYKPiArI2RlZmluZSBQSFlfSERQX01PREVfQ1RSTCAgICAgICAg ICAgICAgIDB4YzAwOAo+ICsjZGVmaW5lIFBIWV9IRFBfQ0xLX0NUTCAgICAgICAgICAgICAgICAg MHhjMDA5Cj4gKyNkZWZpbmUgUEhZX1BNQV9DTU5fQ1RSTDEgICAgICAgICAgICAgICAweGM4MDAK PiArCj4gKyNkZWZpbmUgUkVGX0NMS18yN01IWgkJMjcwMDAwMDAKPiArCj4gK2VudW0gZHBfbGlu a19yYXRlIHsKPiArCVJBVEVfMV82ID0gMTYyMDAwLAo+ICsJUkFURV8yXzEgPSAyMTYwMDAsCj4g KwlSQVRFXzJfNCA9IDI0MzAwMCwKPiArCVJBVEVfMl83ID0gMjcwMDAwLAo+ICsJUkFURV8zXzIg PSAzMjQwMDAsCj4gKwlSQVRFXzRfMyA9IDQzMjAwMCwKPiArCVJBVEVfNV80ID0gNTQwMDAwLAo+ ICsJUkFURV84XzEgPSA4MTAwMDAsCj4gK307Cj4gKwo+ICsjZGVmaW5lIE1BWF9MSU5LX1JBVEUg UkFURV81XzQKPiArCj4gK3N0cnVjdCBwaHlfcGxsX3JlZyB7Cj4gKwl1MTYgdmFsWzddOwo+ICsJ dTMyIGFkZHI7Cj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHBoeV9wbGxfcmVnIHBo eV9wbGxfMjdtX2NmZ1tdID0gewo+ICsJLyogIDEuNjIgICAgMi4xNiAgICAyLjQzICAgIDIuNyAg ICAgMy4yNCAgICA0LjMyICAgIDUuNCAgICAgIHJlZ2lzdGVyIGFkZHJlc3MgKi8KPiArCXt7IDB4 MDEwZSwgMHgwMTBlLCAweDAxMGUsIDB4MDEwZSwgMHgwMTBlLCAweDAxMGUsIDB4MDEwZSB9LCBD TU5fUExMMF9WQ09DQUxfSU5JVF9UTVIgfSwKPiArCXt7IDB4MDAxYiwgMHgwMDFiLCAweDAwMWIs IDB4MDAxYiwgMHgwMDFiLCAweDAwMWIsIDB4MDAxYiB9LCBDTU5fUExMMF9WQ09DQUxfSVRFUl9U TVIgfSwKPiArCXt7IDB4MzBiOSwgMHgzMDg3LCAweDMwOTYsIDB4MzBiNCwgMHgzMGI5LCAweDMw ODcsIDB4MzBiNCB9LCBDTU5fUExMMF9WQ09DQUxfU1RBUlQgfSwKPiArCXt7IDB4MDA3NywgMHgw MDlmLCAweDAwYjMsIDB4MDBjNywgMHgwMDc3LCAweDAwOWYsIDB4MDBjNyB9LCBDTU5fUExMMF9J TlRESVYgfSwKPiArCXt7IDB4ZjlkYSwgMHhmN2NkLCAweGY2YzcsIDB4ZjVjMSwgMHhmOWRhLCAw eGY3Y2QsIDB4ZjVjMSB9LCBDTU5fUExMMF9GUkFDRElWIH0sCj4gKwl7eyAweDAwMWUsIDB4MDAy OCwgMHgwMDJkLCAweDAwMzIsIDB4MDAxZSwgMHgwMDI4LCAweDAwMzIgfSwgQ01OX1BMTDBfSElH SF9USFIgfSwKPiArCXt7IDB4MDAyMCwgMHgwMDIwLCAweDAwMjAsIDB4MDAyMCwgMHgwMDIwLCAw eDAwMjAsIDB4MDAyMCB9LCBDTU5fUExMMF9EU01fRElBRyB9LAo+ICsJe3sgMHgwMDAwLCAweDEw MDAsIDB4MTAwMCwgMHgxMDAwLCAweDAwMDAsIDB4MTAwMCwgMHgxMDAwIH0sIENNTl9QTExTTTBf VVNFUl9ERUZfQ1RSTCB9LAo+ICsJe3sgMHgwMDAwLCAweDAwMDAsIDB4MDAwMCwgMHgwMDAwLCAw eDAwMDAsIDB4MDAwMCwgMHgwMDAwIH0sIENNTl9ESUFHX1BMTDBfT1ZSRCB9LAo+ICsJe3sgMHgw MDAwLCAweDAwMDAsIDB4MDAwMCwgMHgwMDAwLCAweDAwMDAsIDB4MDAwMCwgMHgwMDAwIH0sIENN Tl9ESUFHX1BMTDBfRkJIX09WUkQgfSwKPiArCXt7IDB4MDAwMCwgMHgwMDAwLCAweDAwMDAsIDB4 MDAwMCwgMHgwMDAwLCAweDAwMDAsIDB4MDAwMCB9LCBDTU5fRElBR19QTEwwX0ZCTF9PVlJEIH0s Cj4gKwl7eyAweDAwMDYsIDB4MDAwNywgMHgwMDA3LCAweDAwMDcsIDB4MDAwNiwgMHgwMDA3LCAw eDAwMDcgfSwgQ01OX0RJQUdfUExMMF9WMklfVFVORSB9LAo+ICsJe3sgMHgwMDQzLCAweDAwNDMs IDB4MDA0MywgMHgwMDQyLCAweDAwNDMsIDB4MDA0MywgMHgwMDQyIH0sIENNTl9ESUFHX1BMTDBf Q1BfVFVORSB9LAo+ICsJe3sgMHgwMDA4LCAweDAwMDgsIDB4MDAwOCwgMHgwMDA4LCAweDAwMDgs IDB4MDAwOCwgMHgwMDA4IH0sIENNTl9ESUFHX1BMTDBfTEZfUFJPRyB9LAo+ICsJe3sgMHgwMTAw LCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAxMDAsIDB4MDAwMSwgMHgwMDAxIH0sIENNTl9E SUFHX1BMTDBfUFRBVElTX1RVTkUxIH0sCj4gKwl7eyAweDAwMDcsIDB4MDAwMSwgMHgwMDAxLCAw eDAwMDEsIDB4MDAwNywgMHgwMDAxLCAweDAwMDEgfSwgQ01OX0RJQUdfUExMMF9QVEFUSVNfVFVO RTIgfSwKPiArCXt7IDB4MDAyMCwgMHgwMDIwLCAweDAwMjAsIDB4MDAyMCwgMHgwMDIwLCAweDAw MjAsIDB4MDAyMCB9LCBDTU5fRElBR19QTEwwX1RFU1RfTU9ERX0sCj4gKwl7eyAweDAwMTYsIDB4 MDAxNiwgMHgwMDE2LCAweDAwMTYsIDB4MDAxNiwgMHgwMDE2LCAweDAwMTYgfSwgQ01OX1BTTV9D TEtfQ1RSTCB9Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgY2Ruc19oZHB0eF9kcF9waHkgewo+ICsJdm9p ZCBfX2lvbWVtICpyZWdzOwkvKiBEUFRYIHJlZ2lzdGVycyBiYXNlICovCj4gKwlzdHJ1Y3QgZGV2 aWNlICpkZXY7Cj4gKwlzdHJ1Y3QgcGh5ICpwaHk7Cj4gKwlzdHJ1Y3QgbXV0ZXggbWJveF9tdXRl eDsJLyogbXV0ZXggdG8gcHJvdGVjdCBtYWlsYm94ICovCj4gKwlzdHJ1Y3QgY2xrICpyZWZfY2xr LCAqYXBiX2NsazsKPiArCXUzMiByZWZfY2xrX3JhdGU7Cj4gKwl1MzIgbnVtX2xhbmVzOwo+ICsJ dTMyIGxpbmtfcmF0ZTsKPiArCWJvb2wgcG93ZXJfdXA7Cj4gK307Cj4gKwo+ICtzdGF0aWMgaW50 IGNkbnNfcGh5X3JlZ193cml0ZShzdHJ1Y3QgY2Ruc19oZHB0eF9kcF9waHkgKmNkbnNfcGh5LCB1 MzIgYWRkciwgdTMyIHZhbCkKPiArewo+ICsJcmV0dXJuIGNkbnNfbWhkcF9yZWdfd3JpdGUoY2Ru c19waHksIEFERFJfUEhZX0FGRSArIChhZGRyIDw8IDIpLCB2YWwpOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgdTMyIGNkbnNfcGh5X3JlZ19yZWFkKHN0cnVjdCBjZG5zX2hkcHR4X2RwX3BoeSAqY2Ruc19w aHksIHUzMiBhZGRyKQo+ICt7Cj4gKwl1MzIgcmVnMzI7Cj4gKwo+ICsJY2Ruc19taGRwX3JlZ19y ZWFkKGNkbnNfcGh5LCBBRERSX1BIWV9BRkUgKyAoYWRkciA8PCAyKSwgJnJlZzMyKTsKPiArCXJl dHVybiByZWczMjsKPiArfQo+ICsKPiArc3RhdGljIGludCBsaW5rX3JhdGVfaW5kZXgodTMyIHJh dGUpCj4gK3sKPiArCXN3aXRjaCAocmF0ZSkgewo+ICsJY2FzZSBSQVRFXzFfNjoKPiArCQlyZXR1 cm4gMDsKPiArCWNhc2UgUkFURV8yXzE6Cj4gKwkJcmV0dXJuIDE7Cj4gKwljYXNlIFJBVEVfMl80 Ogo+ICsJCXJldHVybiAyOwo+ICsJY2FzZSBSQVRFXzJfNzoKPiArCQlyZXR1cm4gMzsKPiArCWNh c2UgUkFURV8zXzI6Cj4gKwkJcmV0dXJuIDQ7Cj4gKwljYXNlIFJBVEVfNF8zOgo+ICsJCXJldHVy biA1Owo+ICsJY2FzZSBSQVRFXzVfNDoKPiArCQlyZXR1cm4gNjsKPiArCWRlZmF1bHQ6Cj4gKwkJ cmV0dXJuIC0xOwo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGhkcHR4X2RwX2Nsa19lbmFi bGUoc3RydWN0IGNkbnNfaGRwdHhfZHBfcGh5ICpjZG5zX3BoeSkKPiArewo+ICsJc3RydWN0IGRl dmljZSAqZGV2ID0gY2Ruc19waHktPmRldjsKPiArCXUzMiByZWZfY2xrX3JhdGU7Cj4gKwlpbnQg cmV0Owo+ICsKPiArCWNkbnNfcGh5LT5yZWZfY2xrID0gZGV2bV9jbGtfZ2V0KGRldiwgInJlZiIp Owo+ICsJaWYgKElTX0VSUihjZG5zX3BoeS0+cmVmX2NsaykpIHsKPiArCQlkZXZfZXJyKGRldiwg InBoeSByZWYgY2xvY2sgbm90IGZvdW5kXG4iKTsKPiArCQlyZXR1cm4gUFRSX0VSUihjZG5zX3Bo eS0+cmVmX2Nsayk7Cj4gKwl9Cj4gKwo+ICsJY2Ruc19waHktPmFwYl9jbGsgPSBkZXZtX2Nsa19n ZXQoZGV2LCAiYXBiIik7Cj4gKwlpZiAoSVNfRVJSKGNkbnNfcGh5LT5hcGJfY2xrKSkgewo+ICsJ CWRldl9lcnIoZGV2LCAicGh5IGFwYiBjbG9jayBub3QgZm91bmRcbiIpOwo+ICsJCXJldHVybiBQ VFJfRVJSKGNkbnNfcGh5LT5hcGJfY2xrKTsKPiArCX0KPiArCj4gKwlyZXQgPSBjbGtfcHJlcGFy ZV9lbmFibGUoY2Ruc19waHktPnJlZl9jbGspOwo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIo Y2Ruc19waHktPmRldiwgIkZhaWxlZCB0byBwcmVwYXJlIHJlZiBjbG9ja1xuIik7Cj4gKwkJcmV0 dXJuIHJldDsKPiArCX0KPiArCj4gKwlyZWZfY2xrX3JhdGUgPSBjbGtfZ2V0X3JhdGUoY2Ruc19w aHktPnJlZl9jbGspOwo+ICsJaWYgKCFyZWZfY2xrX3JhdGUpIHsKPiArCQlkZXZfZXJyKGNkbnNf cGh5LT5kZXYsICJGYWlsZWQgdG8gZ2V0IHJlZiBjbG9jayByYXRlXG4iKTsKPiArCQlnb3RvIGVy cl9yZWZfY2xrOwo+ICsJfQo+ICsKPiArCWlmIChyZWZfY2xrX3JhdGUgPT0gUkVGX0NMS18yN01I Wikgewo+ICsJCWNkbnNfcGh5LT5yZWZfY2xrX3JhdGUgPSByZWZfY2xrX3JhdGU7Cj4gKwl9IGVs c2Ugewo+ICsJCWRldl9lcnIoY2Ruc19waHktPmRldiwgIk5vdCBzdXBwb3J0IFJlZiBDbG9jayBS YXRlKCVkSHopXG4iLCByZWZfY2xrX3JhdGUpOwo+ICsJCWdvdG8gZXJyX3JlZl9jbGs7Cj4gKwl9 Cj4gKwo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKGNkbnNfcGh5LT5hcGJfY2xrKTsKPiAr CWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKGNkbnNfcGh5LT5kZXYsICJGYWlsZWQgdG8gcHJlcGFy ZSBhcGIgY2xvY2tcbiIpOwo+ICsJCWdvdG8gZXJyX3JlZl9jbGs7Cj4gKwl9Cj4gKwo+ICsJcmV0 dXJuIDA7Cj4gKwo+ICtlcnJfcmVmX2NsazoKPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShjZG5z X3BoeS0+cmVmX2Nsayk7Cj4gKwlyZXR1cm4gLUVJTlZBTDsKPiArfQo+ICsKPiArc3RhdGljIHZv aWQgaGRwdHhfZHBfY2xrX2Rpc2FibGUoc3RydWN0IGNkbnNfaGRwdHhfZHBfcGh5ICpjZG5zX3Bo eSkKPiArewo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGNkbnNfcGh5LT5yZWZfY2xrKTsKPiAr CWNsa19kaXNhYmxlX3VucHJlcGFyZShjZG5zX3BoeS0+YXBiX2Nsayk7Cj4gK30KPiArCj4gK3N0 YXRpYyB2b2lkIGhkcHR4X2RwX2F1eF9jZmcoc3RydWN0IGNkbnNfaGRwdHhfZHBfcGh5ICpjZG5z X3BoeSkKPiArewo+ICsJLyogUG93ZXIgdXAgQXV4ICovCj4gKwljZG5zX3BoeV9yZWdfd3JpdGUo Y2Ruc19waHksIFRYREFfQ1lBX0FVWERBX0NZQSwgMSk7Cj4gKwo+ICsJY2Ruc19waHlfcmVnX3dy aXRlKGNkbnNfcGh5LCBUWF9ESUdfQ1RSTF9SRUdfMSwgMHgzKTsKPiArCW5kZWxheSgxNTApOwo+ ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBUWF9ESUdfQ1RSTF9SRUdfMiwgMzYpOwo+ ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFRYX0FOQV9D VFJMX1JFR18yLCAweDAxMDApOwo+ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdfd3Jp dGUoY2Ruc19waHksIFRYX0FOQV9DVFJMX1JFR18yLCAweDAzMDApOwo+ICsJbmRlbGF5KDE1MCk7 Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFRYX0FOQV9DVFJMX1JFR18zLCAweDAw MDApOwo+ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFRY X0FOQV9DVFJMX1JFR18xLCAweDIwMDgpOwo+ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9y ZWdfd3JpdGUoY2Ruc19waHksIFRYX0FOQV9DVFJMX1JFR18xLCAweDIwMTgpOwo+ICsJbmRlbGF5 KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFRYX0FOQV9DVFJMX1JFR18x LCAweGEwMTgpOwo+ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19w aHksIFRYX0FOQV9DVFJMX1JFR18yLCAweDAzMGMpOwo+ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5z X3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFRYX0FOQV9DVFJMX1JFR181LCAweDAwMDApOwo+ICsJ bmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFRYX0FOQV9DVFJM X1JFR180LCAweDEwMDEpOwo+ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUo Y2Ruc19waHksIFRYX0FOQV9DVFJMX1JFR18xLCAweGEwOTgpOwo+ICsJbmRlbGF5KDE1MCk7Cj4g KwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFRYX0FOQV9DVFJMX1JFR18xLCAweGExOTgp Owo+ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFRYX0FO QV9DVFJMX1JFR18yLCAweDAzMGQpOwo+ICsJbmRlbGF5KDE1MCk7Cj4gKwljZG5zX3BoeV9yZWdf d3JpdGUoY2Ruc19waHksIFRYX0FOQV9DVFJMX1JFR18yLCAweDAzMGYpOwo+ICt9Cj4gKwo+ICsv KiBQTUEgY29tbW9uIGNvbmZpZ3VyYXRpb24gZm9yIDI3TUh6ICovCj4gK3N0YXRpYyB2b2lkIGhk cHR4X2RwX3BoeV9wbWFfY21uX2NmZ18yN21oeihzdHJ1Y3QgY2Ruc19oZHB0eF9kcF9waHkgKmNk bnNfcGh5KQo+ICt7Cj4gKwl1MzIgbnVtX2xhbmVzID0gY2Ruc19waHktPm51bV9sYW5lczsKPiAr CXUxNiB2YWw7Cj4gKwlpbnQgazsKPiArCj4gKwl2YWwgPSBjZG5zX3BoeV9yZWdfcmVhZChjZG5z X3BoeSwgUEhZX1BNQV9DTU5fQ1RSTDEpOwo+ICsJdmFsICY9IDB4ZmZmNzsKPiArCXZhbCB8PSAw eDAwMDg7CgptYWdpYyBudW1iZXJzPyBhbHNvIHBscyB1c2UgRklFTERfUFJFKCkgdG8gc2V0IGJp dGZpZWxkcwoKPiArCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgUEhZX1BNQV9DTU5fQ1RS TDEsIHZhbCk7Cj4gKwo+ICsJLyogU3RhcnR1cCBzdGF0ZSBtYWNoaW5lIHJlZ2lzdGVycyAqLwo+ ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBDTU5fU1NNX0JJQVNfVE1SLCAweDAwODcp Owo+ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBDTU5fUExMU00wX1BMTEVOX1RNUiwg MHgwMDFiKTsKPiArCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgQ01OX1BMTFNNMF9QTExQ UkVfVE1SLCAweDAwMzYpOwo+ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBDTU5fUExM U00wX1BMTFZSRUZfVE1SLCAweDAwMWIpOwo+ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5 LCBDTU5fUExMU00wX1BMTExPQ0tfVE1SLCAweDAwNmMpOwo+ICsKPiArCS8qIEN1cnJlbnQgY2Fs aWJyYXRpb24gcmVnaXN0ZXJzICovCj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIENN Tl9JQ0FMX0lOSVRfVE1SLCAweDAwNDQpOwo+ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5 LCBDTU5fSUNBTF9JVEVSX1RNUiwgMHgwMDA2KTsKPiArCWNkbnNfcGh5X3JlZ193cml0ZShjZG5z X3BoeSwgQ01OX0lDQUxfQURKX0lOSVRfVE1SLCAweDAwMjIpOwo+ICsJY2Ruc19waHlfcmVnX3dy aXRlKGNkbnNfcGh5LCBDTU5fSUNBTF9BREpfSVRFUl9UTVIsIDB4MDAwNik7Cj4gKwo+ICsJLyog UmVzaXN0b3IgY2FsaWJyYXRpb24gcmVnaXN0ZXJzICovCj4gKwljZG5zX3BoeV9yZWdfd3JpdGUo Y2Ruc19waHksIENNTl9UWFBVQ0FMX0lOSVRfVE1SLCAweDAwMjIpOwo+ICsJY2Ruc19waHlfcmVn X3dyaXRlKGNkbnNfcGh5LCBDTU5fVFhQVUNBTF9JVEVSX1RNUiwgMHgwMDA2KTsKPiArCWNkbnNf cGh5X3JlZ193cml0ZShjZG5zX3BoeSwgQ01OX1RYUFVfQURKX0lOSVRfVE1SLCAweDAwMjIpOwo+ ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBDTU5fVFhQVV9BREpfSVRFUl9UTVIsIDB4 MDAwNik7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIENNTl9UWFBEQ0FMX0lOSVRf VE1SLCAweDAwMjIpOwo+ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBDTU5fVFhQRENB TF9JVEVSX1RNUiwgMHgwMDA2KTsKPiArCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgQ01O X1RYUERfQURKX0lOSVRfVE1SLCAweDAwMjIpOwo+ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNf cGh5LCBDTU5fVFhQRF9BREpfSVRFUl9UTVIsIDB4MDAwNik7Cj4gKwljZG5zX3BoeV9yZWdfd3Jp dGUoY2Ruc19waHksIENNTl9SWENBTF9JTklUX1RNUiwgMHgwMDIyKTsKPiArCWNkbnNfcGh5X3Jl Z193cml0ZShjZG5zX3BoeSwgQ01OX1JYQ0FMX0lURVJfVE1SLCAweDAwMDYpOwo+ICsJY2Ruc19w aHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBDTU5fUlhfQURKX0lOSVRfVE1SLCAweDAwMjIpOwo+ICsJ Y2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBDTU5fUlhfQURKX0lURVJfVE1SLCAweDAwMDYp Owo+ICsKPiArCWZvciAoayA9IDA7IGsgPCBudW1fbGFuZXM7IGsgPSBrICsgMSkgewo+ICsJCS8q IFBvd2VyIHN0YXRlIG1hY2hpbmUgcmVnaXN0ZXJzICovCj4gKwkJY2Ruc19waHlfcmVnX3dyaXRl KGNkbnNfcGh5LCBYQ1ZSX1BTTV9DQUxfVE1SICB8IChrIDw8IDkpLCAweDAxNmQpOwo+ICsJCWNk bnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgWENWUl9QU01fQTBJTl9UTVIgfCAoayA8PCA5KSwg MHgwMTZkKTsKPiArCQkvKiBUcmFuc2NlaXZlciBjb250cm9sIGFuZCBkaWFnbm9zdGljIHJlZ2lz dGVycyAqLwo+ICsJCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgWENWUl9ESUFHX0xBTkVf RkNNX0VOX01HTl9UTVIgfCAoayA8PCA5KSwgMHgwMGEyKTsKPiArCQljZG5zX3BoeV9yZWdfd3Jp dGUoY2Ruc19waHksIFRYX0RJQUdfQkdSRUZfUFJFRFJWX0RFTEFZIHwgKGsgPDwgOSksIDB4MDA5 Nyk7Cj4gKwkJLyogVHJhbnNtaXR0ZXIgcmVjZWl2ZXIgZGV0ZWN0IHJlZ2lzdGVycyAqLwo+ICsJ CWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgVFhfUkNWREVUX0VOX1RNUiB8IChrIDw8IDkp LCAweDBhOGMpOwo+ICsJCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgVFhfUkNWREVUX1NU X1RNUiB8IChrIDw8IDkpLCAweDAwMzYpOwo+ICsJfQo+ICsKPiArCWNkbnNfcGh5X3JlZ193cml0 ZShjZG5zX3BoeSwgVFhfRElBR19BQ1lBXzAsIDEpOwo+ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNk bnNfcGh5LCBUWF9ESUFHX0FDWUFfMSwgMSk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19w aHksIFRYX0RJQUdfQUNZQV8yLCAxKTsKPiArCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwg VFhfRElBR19BQ1lBXzMsIDEpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBoZHB0eF9kcF9waHlf cG1hX2Ntbl9wbGwwXzI3bWh6KHN0cnVjdCBjZG5zX2hkcHR4X2RwX3BoeSAqY2Ruc19waHkpCj4g K3sKPiArCXUzMiBudW1fbGFuZXMgPSBjZG5zX3BoeS0+bnVtX2xhbmVzOwo+ICsJdTMyIGxpbmtf cmF0ZSA9IGNkbnNfcGh5LT5saW5rX3JhdGU7Cj4gKwl1MTYgdmFsOwo+ICsJaW50IGluZGV4LCBp LCBrOwo+ICsKPiArCS8qIERQIFBMTCBkYXRhIHJhdGUgMC8xIGNsb2NrIGRpdmlkZXIgdmFsdWUg Ki8KPiArCXZhbCA9IGNkbnNfcGh5X3JlZ19yZWFkKGNkbnNfcGh5LCBQSFlfSERQX0NMS19DVEwp Owo+ICsJdmFsICY9IDB4MDBmZjsKPiArCWlmIChsaW5rX3JhdGUgPD0gUkFURV8yXzcpCj4gKwkJ dmFsIHw9IDB4MjQwMDsKPiArCWVsc2UKPiArCQl2YWwgfD0gMHgxMjAwOwoKbW9yZSBtYWdpYz8K Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFBIWV9IRFBfQ0xLX0NUTCwgdmFsKTsK PiArCj4gKwkvKiBIaWdoIHNwZWVkIGNsb2NrIDAvMSBkaXYgKi8KPiArCXZhbCA9IGNkbnNfcGh5 X3JlZ19yZWFkKGNkbnNfcGh5LCBDTU5fRElBR19IU0NMS19TRUwpOwo+ICsJdmFsICY9IDB4ZmZj YzsKCmFuZCBoZXJlCgo+ICsJaWYgKGxpbmtfcmF0ZSA8PSBSQVRFXzJfNykKPiArCQl2YWwgfD0g MHgwMDExOwo+ICsJY2Ruc19waHlfcmVnX3dyaXRlKGNkbnNfcGh5LCBDTU5fRElBR19IU0NMS19T RUwsIHZhbCk7Cj4gKwo+ICsJZm9yIChrID0gMDsgayA8IG51bV9sYW5lczsgaysrKSB7Cj4gKwkJ dmFsID0gY2Ruc19waHlfcmVnX3JlYWQoY2Ruc19waHksIChYQ1ZSX0RJQUdfSFNDTEtfU0VMIHwg KGsgPDwgOSkpKTsKPiArCQl2YWwgPSB2YWwgJiAweGNmZmY7Cj4gKwkJaWYgKGxpbmtfcmF0ZSA8 PSBSQVRFXzJfNykKPiArCQkJdmFsIHw9IDB4MTAwMDsKPiArCQljZG5zX3BoeV9yZWdfd3JpdGUo Y2Ruc19waHksIChYQ1ZSX0RJQUdfSFNDTEtfU0VMIHwgKGsgPDwgOSkpLCB2YWwpOwo+ICsJfQo+ ICsKPiArCS8qIERQIFBIWSBQTEwgMjdNSHogY29uZmlndXJhdGlvbiAqLwo+ICsJaW5kZXggPSBs aW5rX3JhdGVfaW5kZXgobGlua19yYXRlKTsKPiArCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpF KHBoeV9wbGxfMjdtX2NmZyk7IGkrKykKPiArCQljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHks IHBoeV9wbGxfMjdtX2NmZ1tpXS5hZGRyLAo+ICsJCQkJICAgcGh5X3BsbF8yN21fY2ZnW2ldLnZh bFtpbmRleF0pOwo+ICsKPiArCS8qIFRyYW5zY2VpdmVyIGNvbnRyb2wgYW5kIGRpYWdub3N0aWMg cmVnaXN0ZXJzICovCj4gKwlmb3IgKGsgPSAwOyBrIDwgbnVtX2xhbmVzOyBrKyspIHsKPiArCQl2 YWwgPSBjZG5zX3BoeV9yZWdfcmVhZChjZG5zX3BoeSwgKFhDVlJfRElBR19QTExEUkNfQ1RSTCB8 IChrIDw8IDkpKSk7Cj4gKwkJdmFsID0gdmFsICYgMHg4ZmZmOwo+ICsJCWlmIChsaW5rX3JhdGUg PD0gUkFURV8yXzcpCj4gKwkJCXZhbCB8PSAweDIwMDA7Cj4gKwkJZWxzZQo+ICsJCQl2YWwgfD0g MHgxMDAwOwo+ICsJCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgKFhDVlJfRElBR19QTExE UkNfQ1RSTCB8IChrIDw8IDkpKSwgdmFsKTsKPiArCX0KPiArCj4gKwlmb3IgKGsgPSAwOyBrIDwg bnVtX2xhbmVzOyBrID0gayArIDEpIHsKPiArCQkvKiBQb3dlciBzdGF0ZSBtYWNoaW5lIHJlZ2lz dGVycyAqLwo+ICsJCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgKFhDVlJfUFNNX1JDVFJM IHwgKGsgPDwgOSkpLCAweGJlZmMpOwo+ICsJCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwg KFRYX1BTQ19BMCB8IChrIDw8IDkpKSwgMHg2Nzk5KTsKPiArCQljZG5zX3BoeV9yZWdfd3JpdGUo Y2Ruc19waHksIChUWF9QU0NfQTEgfCAoayA8PCA5KSksIDB4Njc5OCk7Cj4gKwkJY2Ruc19waHlf cmVnX3dyaXRlKGNkbnNfcGh5LCAoVFhfUFNDX0EyIHwgKGsgPDwgOSkpLCAweDAwOTgpOwo+ICsJ CWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgKFRYX1BTQ19BMyB8IChrIDw8IDkpKSwgMHgw MDk4KTsKPiArCQkvKiBSZWNlaXZlciBjYWxpYnJhdGlvbiBwb3dlciBzdGF0ZSBkZWZpbml0aW9u IHJlZ2lzdGVyICovCj4gKwkJdmFsID0gY2Ruc19waHlfcmVnX3JlYWQoY2Ruc19waHksIFJYX1BT Q19DQUwgfCAoayA8PCA5KSk7Cj4gKwkJdmFsICY9IDB4ZmZiYjsKPiArCQljZG5zX3BoeV9yZWdf d3JpdGUoY2Ruc19waHksIChSWF9QU0NfQ0FMIHwgKGsgPDwgOSkpLCB2YWwpOwo+ICsJCXZhbCA9 IGNkbnNfcGh5X3JlZ19yZWFkKGNkbnNfcGh5LCBSWF9QU0NfQTAgfCAoayA8PCA5KSk7Cj4gKwkJ dmFsICY9IDB4ZmZiYjsKPiArCQljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIChSWF9QU0Nf QTAgfCAoayA8PCA5KSksIHZhbCk7Cj4gKwl9Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGhkcHR4 X2RwX3BoeV9yZWZfY2xvY2tfdHlwZShzdHJ1Y3QgY2Ruc19oZHB0eF9kcF9waHkgKmNkbnNfcGh5 KQo+ICt7Cj4gKwl1MzIgdmFsOwo+ICsKPiArCXZhbCA9IGNkbnNfcGh5X3JlZ19yZWFkKGNkbnNf cGh5LCBQSFlfUE1BX0NNTl9DVFJMMSk7Cj4gKwl2YWwgJj0gMHhmZjhmOwo+ICsJLyoKPiArCSAq IHNpbmdsZSBlbmRlZCByZWZlcmVuY2UgY2xvY2sgKHZhbCB8PSAweDAwMzApOwo+ICsJICogZGlm ZmVyZW50aWFsIGNsb2NrICAodmFsIHw9IDB4MDAwMCk7Cj4gKwkgKgo+ICsJICogZm9yIGRpZmZl cmVudGlhbCBjbG9jayBvbiB0aGUgcmVmY2xrX3AgYW5kCj4gKwkgKiByZWZjbGtfbSBvZmYgY2hp cCBwaW5zOiBDTU5fRElBR19BQ1lBWzhdPTEnYjEKPiArCSAqIGNkbnNfcGh5X3JlZ193cml0ZShj ZG5zX3BoeSwgQ01OX0RJQUdfQUNZQSwgMHgwMTAwKTsKPiArCSAqLwo+ICsJdmFsIHw9IDB4MDAz MDsKPiArCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwgUEhZX1BNQV9DTU5fQ1RSTDEsIHZh bCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgaGRwdHhfZHBfcGh5X3Bvd2VyX3VwKHN0cnVjdCBj ZG5zX2hkcHR4X2RwX3BoeSAqY2Ruc19waHkpCj4gK3sKPiArCXUzMiB2YWwsIGk7Cj4gKwo+ICsJ LyogRW5hYmxlIEhEUCBQTEzigJlzIGZvciBoaWdoIHNwZWVkIGNsb2NrcyAqLwo+ICsJdmFsID0g Y2Ruc19waHlfcmVnX3JlYWQoY2Ruc19waHksIFBIWV9IRFBfQ0xLX0NUTCk7Cj4gKwl2YWwgfD0g KDEgPDwgMCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFBIWV9IRFBfQ0xLX0NU TCwgdmFsKTsKPiArCS8qIFdhaXQgZm9yIFBMTCByZWFkeSBBQ0sgKi8KPiArCWZvciAoaSA9IDA7 IGkgPCAxMDsgaSsrKSB7Cj4gKwkJdmFsID0gY2Ruc19waHlfcmVnX3JlYWQoY2Ruc19waHksIFBI WV9IRFBfQ0xLX0NUTCk7Cj4gKwkJaWYgKHZhbCAmICgxIDw8IDEpKQo+ICsJCQlicmVhazsKPiAr CQltc2xlZXAoMjApOwo+ICsJfQo+ICsJaWYgKGkgPT0gMTApIHsKPiArCQlkZXZfZXJyKGNkbnNf cGh5LT5kZXYsICJXYWl0IFBMTCBBY2sgZmFpbGVkXG4iKTsKPiArCQlyZXR1cm4gLTE7Cj4gKwl9 Cj4gKwo+ICsJLyogRW5hYmxlIEhEUCBQTEzigJlzIGRhdGEgcmF0ZSBhbmQgZnVsbCByYXRlIGNs b2NrcyBvdXQgb2YgUE1BLiAqLwo+ICsJdmFsID0gY2Ruc19waHlfcmVnX3JlYWQoY2Ruc19waHks IFBIWV9IRFBfQ0xLX0NUTCk7Cj4gKwl2YWwgfD0gKDEgPDwgMik7Cj4gKwljZG5zX3BoeV9yZWdf d3JpdGUoY2Ruc19waHksIFBIWV9IRFBfQ0xLX0NUTCwgdmFsKTsKPiArCS8qIFdhaXQgZm9yIFBM TCBjbG9jayBlbmFibGUgQUNLICovCj4gKwlmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgewo+ICsJ CXZhbCA9IGNkbnNfcGh5X3JlZ19yZWFkKGNkbnNfcGh5LCBQSFlfSERQX0NMS19DVEwpOwo+ICsJ CWlmICh2YWwgJiAoMSA8PCAzKSkKPiArCQkJYnJlYWs7Cj4gKwkJbXNsZWVwKDIwKTsKPiArCX0K PiArCWlmIChpID09IDEwKSB7Cj4gKwkJZGV2X2VycihjZG5zX3BoeS0+ZGV2LCAiV2FpdCBQTEwg Y2xvY2sgZW5hYmxlIEFDayBmYWlsZWRcbiIpOwo+ICsJCXJldHVybiAtMTsKPiArCX0KPiArCj4g KwkvKiBDb25maWd1cmUgUEhZIGluIEEyIE1vZGUgKi8KPiArCWNkbnNfcGh5X3JlZ193cml0ZShj ZG5zX3BoeSwgUEhZX0hEUF9NT0RFX0NUUkwsIDB4MDAwNCk7Cj4gKwkvKiBXYWl0IGZvciBQb3dl ciBTdGF0ZSBBMiBBY2sgKi8KPiArCWZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB7Cj4gKwkJdmFs ID0gY2Ruc19waHlfcmVnX3JlYWQoY2Ruc19waHksIFBIWV9IRFBfTU9ERV9DVFJMKTsKPiArCQlp ZiAodmFsICYgKDEgPDwgNikpCj4gKwkJCWJyZWFrOwo+ICsJCW1zbGVlcCgyMCk7Cj4gKwl9Cj4g KwlpZiAoaSA9PSAxMCkgewo+ICsJCWRldl9lcnIoY2Ruc19waHktPmRldiwgIldhaXQgQTIgQWNr IGZhaWxlZFxuIik7Cj4gKwkJcmV0dXJuIC0xOwo+ICsJfQo+ICsKPiArCS8qIENvbmZpZ3VyZSBQ SFkgaW4gQTAgbW9kZSAoUEhZIG11c3QgYmUgaW4gdGhlIEEwIHBvd2VyCj4gKwkgKiBzdGF0ZSBp biBvcmRlciB0byB0cmFuc21pdCBkYXRhKQo+ICsJICovCj4gKwljZG5zX3BoeV9yZWdfd3JpdGUo Y2Ruc19waHksIFBIWV9IRFBfTU9ERV9DVFJMLCAweDAxMDEpOwo+ICsKPiArCS8qIFdhaXQgZm9y IFBvd2VyIFN0YXRlIEEwIEFjayAqLwo+ICsJZm9yIChpID0gMDsgaSA8IDEwOyBpKyspIHsKPiAr CQl2YWwgPSBjZG5zX3BoeV9yZWdfcmVhZChjZG5zX3BoeSwgUEhZX0hEUF9NT0RFX0NUUkwpOwo+ ICsJCWlmICh2YWwgJiAoMSA8PCA0KSkKPiArCQkJYnJlYWs7Cj4gKwkJbXNsZWVwKDIwKTsKPiAr CX0KPiArCWlmIChpID09IDEwKSB7Cj4gKwkJZGV2X2VycihjZG5zX3BoeS0+ZGV2LCAiV2FpdCBB MCBBY2sgZmFpbGVkXG4iKTsKPiArCQlyZXR1cm4gLTE7Cj4gKwl9Cj4gKwo+ICsJY2Ruc19waHkt PnBvd2VyX3VwID0gdHJ1ZTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZv aWQgaGRwdHhfZHBfcGh5X3Bvd2VyX2Rvd24oc3RydWN0IGNkbnNfaGRwdHhfZHBfcGh5ICpjZG5z X3BoeSkKPiArewo+ICsJdTE2IHZhbDsKPiArCWludCBpOwo+ICsKPiArCWlmICghY2Ruc19waHkt PnBvd2VyX3VwKQo+ICsJCXJldHVybjsKPiArCj4gKwkvKiBQbGFjZSB0aGUgUEhZIGxhbmVzIGlu IHRoZSBBMyBwb3dlciBzdGF0ZS4gKi8KPiArCWNkbnNfcGh5X3JlZ193cml0ZShjZG5zX3BoeSwg UEhZX0hEUF9NT0RFX0NUUkwsIDB4OCk7Cj4gKwkvKiBXYWl0IGZvciBQb3dlciBTdGF0ZSBBMyBB Y2sgKi8KPiArCWZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB7Cj4gKwkJdmFsID0gY2Ruc19waHlf cmVnX3JlYWQoY2Ruc19waHksIFBIWV9IRFBfTU9ERV9DVFJMKTsKPiArCQlpZiAodmFsICYgKDEg PDwgNykpCj4gKwkJCWJyZWFrOwo+ICsJCW1zbGVlcCgyMCk7Cj4gKwl9Cj4gKwlpZiAoaSA9PSAx MCkgewo+ICsJCWRldl9lcnIoY2Ruc19waHktPmRldiwgIldhaXQgQTMgQWNrIGZhaWxlZFxuIik7 Cj4gKwkJcmV0dXJuOwo+ICsJfQo+ICsKPiArCS8qIERpc2FibGUgSERQIFBMTOKAmXMgZGF0YSBy YXRlIGFuZCBmdWxsIHJhdGUgY2xvY2tzIG91dCBvZiBQTUEuICovCj4gKwl2YWwgPSBjZG5zX3Bo eV9yZWdfcmVhZChjZG5zX3BoeSwgUEhZX0hEUF9DTEtfQ1RMKTsKPiArCXZhbCAmPSB+KDEgPDwg Mik7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ruc19waHksIFBIWV9IRFBfQ0xLX0NUTCwgdmFs KTsKPiArCS8qIFdhaXQgZm9yIFBMTCBjbG9jayBnYXRlIEFDSyAqLwo+ICsJZm9yIChpID0gMDsg aSA8IDEwOyBpKyspIHsKPiArCQl2YWwgPSBjZG5zX3BoeV9yZWdfcmVhZChjZG5zX3BoeSwgUEhZ X0hEUF9DTEtfQ1RMKTsKPiArCQlpZiAoISh2YWwgJiAoMSA8PCAzKSkpCj4gKwkJCWJyZWFrOwo+ ICsJCW1zbGVlcCgyMCk7Cj4gKwl9Cj4gKwlpZiAoaSA9PSAxMCkgewo+ICsJCWRldl9lcnIoY2Ru c19waHktPmRldiwgIldhaXQgUExMIGNsb2NrIGdhdGUgQWNrIGZhaWxlZFxuIik7Cj4gKwkJcmV0 dXJuOwo+ICsJfQo+ICsKPiArCS8qIERpc2FibGUgSERQIFBMTOKAmXMgZm9yIGhpZ2ggc3BlZWQg Y2xvY2tzICovCj4gKwl2YWwgPSBjZG5zX3BoeV9yZWdfcmVhZChjZG5zX3BoeSwgUEhZX0hEUF9D TEtfQ1RMKTsKPiArCXZhbCAmPSB+KDEgPDwgMCk7Cj4gKwljZG5zX3BoeV9yZWdfd3JpdGUoY2Ru c19waHksIFBIWV9IRFBfQ0xLX0NUTCwgdmFsKTsKPiArCS8qIFdhaXQgZm9yIFBMTCBkaXNhYmxl IEFDSyAqLwo+ICsJZm9yIChpID0gMDsgaSA8IDEwOyBpKyspIHsKPiArCQl2YWwgPSBjZG5zX3Bo eV9yZWdfcmVhZChjZG5zX3BoeSwgUEhZX0hEUF9DTEtfQ1RMKTsKPiArCQlpZiAoISh2YWwgJiAo MSA8PCAxKSkpCj4gKwkJCWJyZWFrOwo+ICsJCW1zbGVlcCgyMCk7Cj4gKwl9Cj4gKwlpZiAoaSA9 PSAxMCkgewo+ICsJCWRldl9lcnIoY2Ruc19waHktPmRldiwgIldhaXQgUExMIGRpc2FibGUgQWNr IGZhaWxlZFxuIik7Cj4gKwkJcmV0dXJuOwo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGNk bnNfaGRwdHhfZHBfcGh5X29uKHN0cnVjdCBwaHkgKnBoeSkKPiArewo+ICsJc3RydWN0IGNkbnNf aGRwdHhfZHBfcGh5ICpjZG5zX3BoeSA9IHBoeV9nZXRfZHJ2ZGF0YShwaHkpOwo+ICsKPiArCXJl dHVybiBoZHB0eF9kcF9waHlfcG93ZXJfdXAoY2Ruc19waHkpOwo+ICt9Cj4gKwo+ICtzdGF0aWMg aW50IGNkbnNfaGRwdHhfZHBfcGh5X29mZihzdHJ1Y3QgcGh5ICpwaHkpCj4gK3sKPiArCXN0cnVj dCBjZG5zX2hkcHR4X2RwX3BoeSAqY2Ruc19waHkgPSBwaHlfZ2V0X2RydmRhdGEocGh5KTsKPiAr Cj4gKwloZHB0eF9kcF9waHlfcG93ZXJfZG93bihjZG5zX3BoeSk7Cj4gKwo+ICsJcmV0dXJuIDA7 Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgY2Ruc19oZHB0eF9kcF9waHlfaW5pdChzdHJ1Y3QgcGh5 ICpwaHkpCj4gK3sKPiArCXN0cnVjdCBjZG5zX2hkcHR4X2RwX3BoeSAqY2Ruc19waHkgPSBwaHlf Z2V0X2RydmRhdGEocGh5KTsKPiArCWludCByZXQ7Cj4gKwo+ICsJaGRwdHhfZHBfcGh5X3JlZl9j bG9ja190eXBlKGNkbnNfcGh5KTsKPiArCj4gKwkvKiBQSFkgcG93ZXIgdXAgKi8KPiArCXJldCA9 IGhkcHR4X2RwX3BoeV9wb3dlcl91cChjZG5zX3BoeSk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQly ZXR1cm4gcmV0Owo+ICsKPiArCWhkcHR4X2RwX2F1eF9jZmcoY2Ruc19waHkpOwo+ICsKPiArCXJl dHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgY2Ruc19oZHB0eF9kcF9jb25maWd1cmUo c3RydWN0IHBoeSAqcGh5LAo+ICsJCQkJICAgdW5pb24gcGh5X2NvbmZpZ3VyZV9vcHRzICpvcHRz KQo+ICt7Cj4gKwlzdHJ1Y3QgY2Ruc19oZHB0eF9kcF9waHkgKmNkbnNfcGh5ID0gcGh5X2dldF9k cnZkYXRhKHBoeSk7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWNkbnNfcGh5LT5saW5rX3JhdGUgPSBv cHRzLT5kcC5saW5rX3JhdGU7Cj4gKwljZG5zX3BoeS0+bnVtX2xhbmVzID0gb3B0cy0+ZHAubGFu ZXM7Cj4gKwo+ICsJaWYgKGNkbnNfcGh5LT5saW5rX3JhdGUgPiBNQVhfTElOS19SQVRFKSB7Cj4g KwkJZGV2X2VycihjZG5zX3BoeS0+ZGV2LCAiTGluayBSYXRlKCVkKSBOb3Qgc3VwcG9ydGVkXG4i LCBjZG5zX3BoeS0+bGlua19yYXRlKTsKPiArCQlyZXR1cm4gZmFsc2U7Cj4gKwl9Cj4gKwo+ICsJ LyogRGlzYWJsZSBwaHkgY2xvY2sgaWYgUEhZIGluIHBvd2VyIHVwIHN0YXRlICovCj4gKwloZHB0 eF9kcF9waHlfcG93ZXJfZG93bihjZG5zX3BoeSk7Cj4gKwo+ICsJaWYgKGNkbnNfcGh5LT5yZWZf Y2xrX3JhdGUgPT0gUkVGX0NMS18yN01IWikgewo+ICsJCWhkcHR4X2RwX3BoeV9wbWFfY21uX2Nm Z18yN21oeihjZG5zX3BoeSk7Cj4gKwkJaGRwdHhfZHBfcGh5X3BtYV9jbW5fcGxsMF8yN21oeihj ZG5zX3BoeSk7Cj4gKwl9IGVsc2Ugewo+ICsJCWRldl9lcnIoY2Ruc19waHktPmRldiwgIk5vdCBz dXBwb3J0IHJlZiBjbG9jayByYXRlXG4iKTsKPiArCX0KPiArCj4gKwkvKiBQSFkgcG93ZXIgdXAg Ki8KPiArCXJldCA9IGhkcHR4X2RwX3BoeV9wb3dlcl91cChjZG5zX3BoeSk7Cj4gKwo+ICsJcmV0 dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBwaHlfb3BzIGNkbnNfaGRw dHhfZHBfcGh5X29wcyA9IHsKPiArCS5pbml0ID0gY2Ruc19oZHB0eF9kcF9waHlfaW5pdCwKPiAr CS5jb25maWd1cmUgPSBjZG5zX2hkcHR4X2RwX2NvbmZpZ3VyZSwKPiArCS5wb3dlcl9vbiA9IGNk bnNfaGRwdHhfZHBfcGh5X29uLAo+ICsJLnBvd2VyX29mZiA9IGNkbnNfaGRwdHhfZHBfcGh5X29m ZiwKPiArCS5vd25lciA9IFRISVNfTU9EVUxFLAo+ICt9Owo+ICsKPiArc3RhdGljIGludCBjZG5z X2hkcHR4X2RwX3BoeV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICt7Cj4g KwlzdHJ1Y3QgY2Ruc19oZHB0eF9kcF9waHkgKmNkbnNfcGh5Owo+ICsJc3RydWN0IGRldmljZSAq ZGV2ID0gJnBkZXYtPmRldjsKPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbm9kZSA9IGRldi0+b2Zf bm9kZTsKPiArCXN0cnVjdCBwaHlfcHJvdmlkZXIgKnBoeV9wcm92aWRlcjsKPiArCXN0cnVjdCBy ZXNvdXJjZSAqcmVzOwo+ICsJc3RydWN0IHBoeSAqcGh5Owo+ICsJaW50IHJldDsKPiArCj4gKwlj ZG5zX3BoeSA9IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqY2Ruc19waHkpLCBHRlBfS0VSTkVM KTsKPiArCWlmICghY2Ruc19waHkpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJZGV2X3Nl dF9kcnZkYXRhKGRldiwgY2Ruc19waHkpOwo+ICsJY2Ruc19waHktPmRldiA9IGRldjsKPiArCW11 dGV4X2luaXQoJmNkbnNfcGh5LT5tYm94X211dGV4KTsKPiArCj4gKwlyZXMgPSBwbGF0Zm9ybV9n ZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOwo+ICsJaWYgKCFyZXMpCj4gKwkJ cmV0dXJuIC1FTk9ERVY7Cj4gKwljZG5zX3BoeS0+cmVncyA9IGRldm1faW9yZW1hcChkZXYsIHJl cy0+c3RhcnQsIHJlc291cmNlX3NpemUocmVzKSk7Cj4gKwlpZiAoSVNfRVJSKGNkbnNfcGh5LT5y ZWdzKSkKPiArCQlyZXR1cm4gUFRSX0VSUihjZG5zX3BoeS0+cmVncyk7Cj4gKwo+ICsJcGh5ID0g ZGV2bV9waHlfY3JlYXRlKGRldiwgbm9kZSwgJmNkbnNfaGRwdHhfZHBfcGh5X29wcyk7Cj4gKwlp ZiAoSVNfRVJSKHBoeSkpCj4gKwkJcmV0dXJuIFBUUl9FUlIocGh5KTsKPiArCj4gKwlwaHktPmF0 dHJzLm1vZGUgPSBQSFlfTU9ERV9EUDsKPiArCWNkbnNfcGh5LT5waHkgPSBwaHk7Cj4gKwlwaHlf c2V0X2RydmRhdGEocGh5LCBjZG5zX3BoeSk7Cj4gKwo+ICsJcmV0ID0gaGRwdHhfZHBfY2xrX2Vu YWJsZShjZG5zX3BoeSk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X2VycihkZXYsICJJbml0IGNs ayBmYWlsXG4iKTsKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCX0KPiArCj4gKwlwaHlfcHJvdmlk ZXIgPSBkZXZtX29mX3BoeV9wcm92aWRlcl9yZWdpc3RlcihkZXYsIG9mX3BoeV9zaW1wbGVfeGxh dGUpOwo+ICsJaWYgKElTX0VSUihwaHlfcHJvdmlkZXIpKSB7Cj4gKwkJcmV0ID0gUFRSX0VSUihw aHlfcHJvdmlkZXIpOwo+ICsJCWdvdG8gY2xrX2Rpc2FibGU7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJu IDA7Cj4gKwo+ICtjbGtfZGlzYWJsZToKPiArCWhkcHR4X2RwX2Nsa19kaXNhYmxlKGNkbnNfcGh5 KTsKPiArCj4gKwlyZXR1cm4gLUVJTlZBTDsKPiArfQo+ICsKPiArc3RhdGljIGludCBjZG5zX2hk cHR4X2RwX3BoeV9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJ c3RydWN0IGNkbnNfaGRwdHhfZHBfcGh5ICpjZG5zX3BoeSA9IHBsYXRmb3JtX2dldF9kcnZkYXRh KHBkZXYpOwo+ICsKPiArCWhkcHR4X2RwX2Nsa19kaXNhYmxlKGNkbnNfcGh5KTsKPiArCj4gKwly ZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgY2Ru c19oZHB0eF9kcF9waHlfb2ZfbWF0Y2hbXSA9IHsKPiArCXsuY29tcGF0aWJsZSA9ICJmc2wsaW14 OG1xLWRwLXBoeSIgfSwKPiArCXsgLyogc2VudGluZWwgKi8gfQo+ICt9Owo+ICtNT0RVTEVfREVW SUNFX1RBQkxFKG9mLCBjZG5zX2hkcHR4X2RwX3BoeV9vZl9tYXRjaCk7Cj4gKwo+ICtzdGF0aWMg c3RydWN0IHBsYXRmb3JtX2RyaXZlciBjZG5zX2hkcHR4X2RwX3BoeV9kcml2ZXIgPSB7Cj4gKwku cHJvYmUgPSBjZG5zX2hkcHR4X2RwX3BoeV9wcm9iZSwKPiArCS5yZW1vdmUgPSBjZG5zX2hkcHR4 X2RwX3BoeV9yZW1vdmUsCj4gKwkuZHJpdmVyID0gewo+ICsJCS5uYW1lCT0gImNkbnMtaGRwdHgt ZHAtcGh5IiwKPiArCQkub2ZfbWF0Y2hfdGFibGUJPSBjZG5zX2hkcHR4X2RwX3BoeV9vZl9tYXRj aCwKPiArCX0KPiArfTsKPiArbW9kdWxlX3BsYXRmb3JtX2RyaXZlcihjZG5zX2hkcHR4X2RwX3Bo eV9kcml2ZXIpOwo+ICsKPiArTU9EVUxFX0FVVEhPUigiU2FuZG9yIFl1IDxzYW5kb3IueXVAbnhw LmNvbT4iKTsKPiArTU9EVUxFX0RFU0NSSVBUSU9OKCJDYWRlbmNlIEhEUC1UWCBEaXNwbGF5UG9y dCBQSFkgZHJpdmVyIik7Cj4gK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsKPiAtLSAKPiAyLjM0LjEK Ci0tIAp+Vmlub2QKCi0tIApsaW51eC1waHkgbWFpbGluZyBsaXN0CmxpbnV4LXBoeUBsaXN0cy5p bmZyYWRlYWQub3JnCmh0dHBzOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZv L2xpbnV4LXBoeQo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C881C001B0 for ; Mon, 24 Jul 2023 10:51:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232685AbjGXKv6 (ORCPT ); Mon, 24 Jul 2023 06:51:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231524AbjGXKv5 (ORCPT ); Mon, 24 Jul 2023 06:51:57 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8169011F; Mon, 24 Jul 2023 03:51:51 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 1070361070; Mon, 24 Jul 2023 10:51:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C40AC433C7; Mon, 24 Jul 2023 10:51:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690195910; bh=Hm4KpRgolrbkVpbCQNLJbZKNI2aGi1klArYlS2xQMGM=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=dU8zYDo5/5EjJOeprdTvhp9BX+oIjNaKE4W+cYWvjy7w2i1Ufqbg+q58mQ6Zakowq sYA0K5Jtn0l7k/RKfSt+IIhdw9weUbjGdkYa7XeHQ3ZozEaUzvJb/dmGu1EcdUD91y 92vTj/gJyZImKETv1DlDpmgsb2GvyceIpNOA2dPQxuIk83Q+o6HYcfjqLJarNxbNZD d5YeZHkTHIyfaGUP9dPvkikLFWXe2pbydbf9grdJvggd/7J6lu7nQ1Nu7HIKDs1ZNw X7ooUtyvsZbQ6s9rJROEoFPQPbPUBNXLGbfdhBc8akMNGjezhTDym2huLL7PBcCx9c z7pkm7C2RszZw== Date: Mon, 24 Jul 2023 16:21:45 +0530 From: Vinod Koul To: Sandor Yu Cc: andrzej.hajda@intel.com, neil.armstrong@linaro.org, Laurent.pinchart@ideasonboard.com, jonas@kwiboo.se, jernej.skrabec@gmail.com, airlied@gmail.com, daniel@ffwll.ch, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com, dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, kernel@pengutronix.de, linux-imx@nxp.com, oliver.brown@nxp.com, alexander.stein@ew.tq-group.com, sam@ravnborg.org Subject: Re: [PATCH v7 6/7] phy: freescale: Add DisplayPort PHY driver for i.MX8MQ Message-ID: References: <50f342972001f079a0946f7718c6e3fa6aed9503.1689580812.git.Sandor.yu@nxp.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <50f342972001f079a0946f7718c6e3fa6aed9503.1689580812.git.Sandor.yu@nxp.com> Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org On 17-07-23, 16:03, Sandor Yu wrote: > Add Cadence HDP-TX DisplayPort PHY driver for i.MX8MQ > > Cadence HDP-TX PHY could be put in either DP mode or > HDMI mode base on the configuration chosen. > DisplayPort PHY mode is configurated in the driver. > > Signed-off-by: Sandor Yu > --- > drivers/phy/freescale/Kconfig | 9 + > drivers/phy/freescale/Makefile | 1 + > drivers/phy/freescale/phy-fsl-imx8mq-dp.c | 698 ++++++++++++++++++++++ > 3 files changed, 708 insertions(+) > create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-dp.c > > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig > index 853958fb2c06..2999ba1e57d0 100644 > --- a/drivers/phy/freescale/Kconfig > +++ b/drivers/phy/freescale/Kconfig > @@ -35,6 +35,15 @@ config PHY_FSL_IMX8M_PCIE > Enable this to add support for the PCIE PHY as found on > i.MX8M family of SOCs. > > +config PHY_FSL_IMX8MQ_DP_PHY > + tristate "Freescale i.MX8MQ DP PHY support" > + depends on OF && HAS_IOMEM > + depends on COMMON_CLK > + select GENERIC_PHY > + help > + Enable this to support the Cadence HDPTX DP PHY driver > + on i.MX8MQ SOC. > + > endif > > config PHY_FSL_LYNX_28G > diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile > index cedb328bc4d2..915a429d9fbc 100644 > --- a/drivers/phy/freescale/Makefile > +++ b/drivers/phy/freescale/Makefile > @@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY) += phy-fsl-imx8qm-lvds-phy.o > obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY) += phy-fsl-imx8-mipi-dphy.o > obj-$(CONFIG_PHY_FSL_IMX8M_PCIE) += phy-fsl-imx8m-pcie.o > obj-$(CONFIG_PHY_FSL_LYNX_28G) += phy-fsl-lynx-28g.o > +obj-$(CONFIG_PHY_FSL_IMX8MQ_DP_PHY) += phy-fsl-imx8mq-dp.o > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-dp.c b/drivers/phy/freescale/phy-fsl-imx8mq-dp.c > new file mode 100644 > index 000000000000..415273ac6aa5 > --- /dev/null > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-dp.c > @@ -0,0 +1,698 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Cadence HDP-TX Display Port Interface (DP) PHY driver > + * > + * Copyright (C) 2022 NXP Semiconductor, Inc. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#define ADDR_PHY_AFE 0x80000 > + > +/* PHY registers */ > +#define CMN_SSM_BIAS_TMR 0x0022 > +#define CMN_PLLSM0_PLLEN_TMR 0x0029 > +#define CMN_PLLSM0_PLLPRE_TMR 0x002a > +#define CMN_PLLSM0_PLLVREF_TMR 0x002b > +#define CMN_PLLSM0_PLLLOCK_TMR 0x002c > +#define CMN_PLLSM0_USER_DEF_CTRL 0x002f > +#define CMN_PSM_CLK_CTRL 0x0061 > +#define CMN_PLL0_VCOCAL_START 0x0081 > +#define CMN_PLL0_VCOCAL_INIT_TMR 0x0084 > +#define CMN_PLL0_VCOCAL_ITER_TMR 0x0085 > +#define CMN_PLL0_INTDIV 0x0094 > +#define CMN_PLL0_FRACDIV 0x0095 > +#define CMN_PLL0_HIGH_THR 0x0096 > +#define CMN_PLL0_DSM_DIAG 0x0097 > +#define CMN_PLL0_SS_CTRL2 0x0099 > +#define CMN_ICAL_INIT_TMR 0x00c4 > +#define CMN_ICAL_ITER_TMR 0x00c5 > +#define CMN_RXCAL_INIT_TMR 0x00d4 > +#define CMN_RXCAL_ITER_TMR 0x00d5 > +#define CMN_TXPUCAL_INIT_TMR 0x00e4 > +#define CMN_TXPUCAL_ITER_TMR 0x00e5 > +#define CMN_TXPDCAL_INIT_TMR 0x00f4 > +#define CMN_TXPDCAL_ITER_TMR 0x00f5 > +#define CMN_ICAL_ADJ_INIT_TMR 0x0102 > +#define CMN_ICAL_ADJ_ITER_TMR 0x0103 > +#define CMN_RX_ADJ_INIT_TMR 0x0106 > +#define CMN_RX_ADJ_ITER_TMR 0x0107 > +#define CMN_TXPU_ADJ_INIT_TMR 0x010a > +#define CMN_TXPU_ADJ_ITER_TMR 0x010b > +#define CMN_TXPD_ADJ_INIT_TMR 0x010e > +#define CMN_TXPD_ADJ_ITER_TMR 0x010f > +#define CMN_DIAG_PLL0_FBH_OVRD 0x01c0 > +#define CMN_DIAG_PLL0_FBL_OVRD 0x01c1 > +#define CMN_DIAG_PLL0_OVRD 0x01c2 > +#define CMN_DIAG_PLL0_TEST_MODE 0x01c4 > +#define CMN_DIAG_PLL0_V2I_TUNE 0x01c5 > +#define CMN_DIAG_PLL0_CP_TUNE 0x01c6 > +#define CMN_DIAG_PLL0_LF_PROG 0x01c7 > +#define CMN_DIAG_PLL0_PTATIS_TUNE1 0x01c8 > +#define CMN_DIAG_PLL0_PTATIS_TUNE2 0x01c9 > +#define CMN_DIAG_HSCLK_SEL 0x01e0 > +#define CMN_DIAG_PER_CAL_ADJ 0x01ec > +#define CMN_DIAG_CAL_CTRL 0x01ed > +#define CMN_DIAG_ACYA 0x01ff > +#define XCVR_PSM_RCTRL 0x4001 > +#define XCVR_PSM_CAL_TMR 0x4002 > +#define XCVR_PSM_A0IN_TMR 0x4003 > +#define TX_TXCC_CAL_SCLR_MULT_0 0x4047 > +#define TX_TXCC_CPOST_MULT_00_0 0x404c > +#define XCVR_DIAG_PLLDRC_CTRL 0x40e0 > +#define XCVR_DIAG_PLLDRC_CTRL 0x40e0 > +#define XCVR_DIAG_HSCLK_SEL 0x40e1 > +#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40f2 > +#define TX_PSC_A0 0x4100 > +#define TX_PSC_A1 0x4101 > +#define TX_PSC_A2 0x4102 > +#define TX_PSC_A3 0x4103 > +#define TX_RCVDET_EN_TMR 0x4122 > +#define TX_RCVDET_ST_TMR 0x4123 > +#define TX_DIAG_BGREF_PREDRV_DELAY 0x41e7 > +#define TX_DIAG_BGREF_PREDRV_DELAY 0x41e7 > +#define TX_DIAG_ACYA_0 0x41ff > +#define TX_DIAG_ACYA_1 0x43ff > +#define TX_DIAG_ACYA_2 0x45ff > +#define TX_DIAG_ACYA_3 0x47ff > +#define TX_ANA_CTRL_REG_1 0x5020 > +#define TX_ANA_CTRL_REG_2 0x5021 > +#define TX_DIG_CTRL_REG_1 0x5023 > +#define TX_DIG_CTRL_REG_2 0x5024 > +#define TXDA_CYA_AUXDA_CYA 0x5025 > +#define TX_ANA_CTRL_REG_3 0x5026 > +#define TX_ANA_CTRL_REG_4 0x5027 > +#define TX_ANA_CTRL_REG_5 0x5029 > +#define RX_PSC_A0 0x8000 > +#define RX_PSC_CAL 0x8006 > +#define PHY_HDP_MODE_CTRL 0xc008 > +#define PHY_HDP_CLK_CTL 0xc009 > +#define PHY_PMA_CMN_CTRL1 0xc800 > + > +#define REF_CLK_27MHZ 27000000 > + > +enum dp_link_rate { > + RATE_1_6 = 162000, > + RATE_2_1 = 216000, > + RATE_2_4 = 243000, > + RATE_2_7 = 270000, > + RATE_3_2 = 324000, > + RATE_4_3 = 432000, > + RATE_5_4 = 540000, > + RATE_8_1 = 810000, > +}; > + > +#define MAX_LINK_RATE RATE_5_4 > + > +struct phy_pll_reg { > + u16 val[7]; > + u32 addr; > +}; > + > +static const struct phy_pll_reg phy_pll_27m_cfg[] = { > + /* 1.62 2.16 2.43 2.7 3.24 4.32 5.4 register address */ > + {{ 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e }, CMN_PLL0_VCOCAL_INIT_TMR }, > + {{ 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b }, CMN_PLL0_VCOCAL_ITER_TMR }, > + {{ 0x30b9, 0x3087, 0x3096, 0x30b4, 0x30b9, 0x3087, 0x30b4 }, CMN_PLL0_VCOCAL_START }, > + {{ 0x0077, 0x009f, 0x00b3, 0x00c7, 0x0077, 0x009f, 0x00c7 }, CMN_PLL0_INTDIV }, > + {{ 0xf9da, 0xf7cd, 0xf6c7, 0xf5c1, 0xf9da, 0xf7cd, 0xf5c1 }, CMN_PLL0_FRACDIV }, > + {{ 0x001e, 0x0028, 0x002d, 0x0032, 0x001e, 0x0028, 0x0032 }, CMN_PLL0_HIGH_THR }, > + {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_PLL0_DSM_DIAG }, > + {{ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000 }, CMN_PLLSM0_USER_DEF_CTRL }, > + {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_OVRD }, > + {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBH_OVRD }, > + {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBL_OVRD }, > + {{ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007 }, CMN_DIAG_PLL0_V2I_TUNE }, > + {{ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042 }, CMN_DIAG_PLL0_CP_TUNE }, > + {{ 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008 }, CMN_DIAG_PLL0_LF_PROG }, > + {{ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE1 }, > + {{ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE2 }, > + {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_DIAG_PLL0_TEST_MODE}, > + {{ 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016 }, CMN_PSM_CLK_CTRL } > +}; > + > +struct cdns_hdptx_dp_phy { > + void __iomem *regs; /* DPTX registers base */ > + struct device *dev; > + struct phy *phy; > + struct mutex mbox_mutex; /* mutex to protect mailbox */ > + struct clk *ref_clk, *apb_clk; > + u32 ref_clk_rate; > + u32 num_lanes; > + u32 link_rate; > + bool power_up; > +}; > + > +static int cdns_phy_reg_write(struct cdns_hdptx_dp_phy *cdns_phy, u32 addr, u32 val) > +{ > + return cdns_mhdp_reg_write(cdns_phy, ADDR_PHY_AFE + (addr << 2), val); > +} > + > +static u32 cdns_phy_reg_read(struct cdns_hdptx_dp_phy *cdns_phy, u32 addr) > +{ > + u32 reg32; > + > + cdns_mhdp_reg_read(cdns_phy, ADDR_PHY_AFE + (addr << 2), ®32); > + return reg32; > +} > + > +static int link_rate_index(u32 rate) > +{ > + switch (rate) { > + case RATE_1_6: > + return 0; > + case RATE_2_1: > + return 1; > + case RATE_2_4: > + return 2; > + case RATE_2_7: > + return 3; > + case RATE_3_2: > + return 4; > + case RATE_4_3: > + return 5; > + case RATE_5_4: > + return 6; > + default: > + return -1; > + } > +} > + > +static int hdptx_dp_clk_enable(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + struct device *dev = cdns_phy->dev; > + u32 ref_clk_rate; > + int ret; > + > + cdns_phy->ref_clk = devm_clk_get(dev, "ref"); > + if (IS_ERR(cdns_phy->ref_clk)) { > + dev_err(dev, "phy ref clock not found\n"); > + return PTR_ERR(cdns_phy->ref_clk); > + } > + > + cdns_phy->apb_clk = devm_clk_get(dev, "apb"); > + if (IS_ERR(cdns_phy->apb_clk)) { > + dev_err(dev, "phy apb clock not found\n"); > + return PTR_ERR(cdns_phy->apb_clk); > + } > + > + ret = clk_prepare_enable(cdns_phy->ref_clk); > + if (ret) { > + dev_err(cdns_phy->dev, "Failed to prepare ref clock\n"); > + return ret; > + } > + > + ref_clk_rate = clk_get_rate(cdns_phy->ref_clk); > + if (!ref_clk_rate) { > + dev_err(cdns_phy->dev, "Failed to get ref clock rate\n"); > + goto err_ref_clk; > + } > + > + if (ref_clk_rate == REF_CLK_27MHZ) { > + cdns_phy->ref_clk_rate = ref_clk_rate; > + } else { > + dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate); > + goto err_ref_clk; > + } > + > + ret = clk_prepare_enable(cdns_phy->apb_clk); > + if (ret) { > + dev_err(cdns_phy->dev, "Failed to prepare apb clock\n"); > + goto err_ref_clk; > + } > + > + return 0; > + > +err_ref_clk: > + clk_disable_unprepare(cdns_phy->ref_clk); > + return -EINVAL; > +} > + > +static void hdptx_dp_clk_disable(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + clk_disable_unprepare(cdns_phy->ref_clk); > + clk_disable_unprepare(cdns_phy->apb_clk); > +} > + > +static void hdptx_dp_aux_cfg(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + /* Power up Aux */ > + cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 1); > + > + cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_1, 0x3); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, 36); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa018); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0000); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x1001); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa098); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa198); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f); > +} > + > +/* PMA common configuration for 27MHz */ > +static void hdptx_dp_phy_pma_cmn_cfg_27mhz(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u32 num_lanes = cdns_phy->num_lanes; > + u16 val; > + int k; > + > + val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); > + val &= 0xfff7; > + val |= 0x0008; magic numbers? also pls use FIELD_PRE() to set bitfields > + cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); > + > + /* Startup state machine registers */ > + cdns_phy_reg_write(cdns_phy, CMN_SSM_BIAS_TMR, 0x0087); > + cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLEN_TMR, 0x001b); > + cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLPRE_TMR, 0x0036); > + cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLVREF_TMR, 0x001b); > + cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLLOCK_TMR, 0x006c); > + > + /* Current calibration registers */ > + cdns_phy_reg_write(cdns_phy, CMN_ICAL_INIT_TMR, 0x0044); > + cdns_phy_reg_write(cdns_phy, CMN_ICAL_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_ITER_TMR, 0x0006); > + > + /* Resistor calibration registers */ > + cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_RXCAL_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_RXCAL_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_ITER_TMR, 0x0006); > + > + for (k = 0; k < num_lanes; k = k + 1) { > + /* Power state machine registers */ > + cdns_phy_reg_write(cdns_phy, XCVR_PSM_CAL_TMR | (k << 9), 0x016d); > + cdns_phy_reg_write(cdns_phy, XCVR_PSM_A0IN_TMR | (k << 9), 0x016d); > + /* Transceiver control and diagnostic registers */ > + cdns_phy_reg_write(cdns_phy, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x00a2); > + cdns_phy_reg_write(cdns_phy, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9), 0x0097); > + /* Transmitter receiver detect registers */ > + cdns_phy_reg_write(cdns_phy, TX_RCVDET_EN_TMR | (k << 9), 0x0a8c); > + cdns_phy_reg_write(cdns_phy, TX_RCVDET_ST_TMR | (k << 9), 0x0036); > + } > + > + cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1); > + cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1); > + cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1); > + cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1); > +} > + > +static void hdptx_dp_phy_pma_cmn_pll0_27mhz(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u32 num_lanes = cdns_phy->num_lanes; > + u32 link_rate = cdns_phy->link_rate; > + u16 val; > + int index, i, k; > + > + /* DP PLL data rate 0/1 clock divider value */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val &= 0x00ff; > + if (link_rate <= RATE_2_7) > + val |= 0x2400; > + else > + val |= 0x1200; more magic? > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + > + /* High speed clock 0/1 div */ > + val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL); > + val &= 0xffcc; and here > + if (link_rate <= RATE_2_7) > + val |= 0x0011; > + cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val); > + > + for (k = 0; k < num_lanes; k++) { > + val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9))); > + val = val & 0xcfff; > + if (link_rate <= RATE_2_7) > + val |= 0x1000; > + cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val); > + } > + > + /* DP PHY PLL 27MHz configuration */ > + index = link_rate_index(link_rate); > + for (i = 0; i < ARRAY_SIZE(phy_pll_27m_cfg); i++) > + cdns_phy_reg_write(cdns_phy, phy_pll_27m_cfg[i].addr, > + phy_pll_27m_cfg[i].val[index]); > + > + /* Transceiver control and diagnostic registers */ > + for (k = 0; k < num_lanes; k++) { > + val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9))); > + val = val & 0x8fff; > + if (link_rate <= RATE_2_7) > + val |= 0x2000; > + else > + val |= 0x1000; > + cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val); > + } > + > + for (k = 0; k < num_lanes; k = k + 1) { > + /* Power state machine registers */ > + cdns_phy_reg_write(cdns_phy, (XCVR_PSM_RCTRL | (k << 9)), 0xbefc); > + cdns_phy_reg_write(cdns_phy, (TX_PSC_A0 | (k << 9)), 0x6799); > + cdns_phy_reg_write(cdns_phy, (TX_PSC_A1 | (k << 9)), 0x6798); > + cdns_phy_reg_write(cdns_phy, (TX_PSC_A2 | (k << 9)), 0x0098); > + cdns_phy_reg_write(cdns_phy, (TX_PSC_A3 | (k << 9)), 0x0098); > + /* Receiver calibration power state definition register */ > + val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9)); > + val &= 0xffbb; > + cdns_phy_reg_write(cdns_phy, (RX_PSC_CAL | (k << 9)), val); > + val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9)); > + val &= 0xffbb; > + cdns_phy_reg_write(cdns_phy, (RX_PSC_A0 | (k << 9)), val); > + } > +} > + > +static void hdptx_dp_phy_ref_clock_type(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u32 val; > + > + val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); > + val &= 0xff8f; > + /* > + * single ended reference clock (val |= 0x0030); > + * differential clock (val |= 0x0000); > + * > + * for differential clock on the refclk_p and > + * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1 > + * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100); > + */ > + val |= 0x0030; > + cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); > +} > + > +static int hdptx_dp_phy_power_up(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u32 val, i; > + > + /* Enable HDP PLL’s for high speed clocks */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val |= (1 << 0); > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + /* Wait for PLL ready ACK */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + if (val & (1 << 1)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait PLL Ack failed\n"); > + return -1; > + } > + > + /* Enable HDP PLL’s data rate and full rate clocks out of PMA. */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val |= (1 << 2); > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + /* Wait for PLL clock enable ACK */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + if (val & (1 << 3)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait PLL clock enable ACk failed\n"); > + return -1; > + } > + > + /* Configure PHY in A2 Mode */ > + cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, 0x0004); > + /* Wait for Power State A2 Ack */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL); > + if (val & (1 << 6)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait A2 Ack failed\n"); > + return -1; > + } > + > + /* Configure PHY in A0 mode (PHY must be in the A0 power > + * state in order to transmit data) > + */ > + cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, 0x0101); > + > + /* Wait for Power State A0 Ack */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL); > + if (val & (1 << 4)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait A0 Ack failed\n"); > + return -1; > + } > + > + cdns_phy->power_up = true; > + > + return 0; > +} > + > +static void hdptx_dp_phy_power_down(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u16 val; > + int i; > + > + if (!cdns_phy->power_up) > + return; > + > + /* Place the PHY lanes in the A3 power state. */ > + cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, 0x8); > + /* Wait for Power State A3 Ack */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL); > + if (val & (1 << 7)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait A3 Ack failed\n"); > + return; > + } > + > + /* Disable HDP PLL’s data rate and full rate clocks out of PMA. */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val &= ~(1 << 2); > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + /* Wait for PLL clock gate ACK */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + if (!(val & (1 << 3))) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait PLL clock gate Ack failed\n"); > + return; > + } > + > + /* Disable HDP PLL’s for high speed clocks */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val &= ~(1 << 0); > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + /* Wait for PLL disable ACK */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + if (!(val & (1 << 1))) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait PLL disable Ack failed\n"); > + return; > + } > +} > + > +static int cdns_hdptx_dp_phy_on(struct phy *phy) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy); > + > + return hdptx_dp_phy_power_up(cdns_phy); > +} > + > +static int cdns_hdptx_dp_phy_off(struct phy *phy) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy); > + > + hdptx_dp_phy_power_down(cdns_phy); > + > + return 0; > +} > + > +static int cdns_hdptx_dp_phy_init(struct phy *phy) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy); > + int ret; > + > + hdptx_dp_phy_ref_clock_type(cdns_phy); > + > + /* PHY power up */ > + ret = hdptx_dp_phy_power_up(cdns_phy); > + if (ret < 0) > + return ret; > + > + hdptx_dp_aux_cfg(cdns_phy); > + > + return ret; > +} > + > +static int cdns_hdptx_dp_configure(struct phy *phy, > + union phy_configure_opts *opts) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy); > + int ret; > + > + cdns_phy->link_rate = opts->dp.link_rate; > + cdns_phy->num_lanes = opts->dp.lanes; > + > + if (cdns_phy->link_rate > MAX_LINK_RATE) { > + dev_err(cdns_phy->dev, "Link Rate(%d) Not supported\n", cdns_phy->link_rate); > + return false; > + } > + > + /* Disable phy clock if PHY in power up state */ > + hdptx_dp_phy_power_down(cdns_phy); > + > + if (cdns_phy->ref_clk_rate == REF_CLK_27MHZ) { > + hdptx_dp_phy_pma_cmn_cfg_27mhz(cdns_phy); > + hdptx_dp_phy_pma_cmn_pll0_27mhz(cdns_phy); > + } else { > + dev_err(cdns_phy->dev, "Not support ref clock rate\n"); > + } > + > + /* PHY power up */ > + ret = hdptx_dp_phy_power_up(cdns_phy); > + > + return ret; > +} > + > +static const struct phy_ops cdns_hdptx_dp_phy_ops = { > + .init = cdns_hdptx_dp_phy_init, > + .configure = cdns_hdptx_dp_configure, > + .power_on = cdns_hdptx_dp_phy_on, > + .power_off = cdns_hdptx_dp_phy_off, > + .owner = THIS_MODULE, > +}; > + > +static int cdns_hdptx_dp_phy_probe(struct platform_device *pdev) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy; > + struct device *dev = &pdev->dev; > + struct device_node *node = dev->of_node; > + struct phy_provider *phy_provider; > + struct resource *res; > + struct phy *phy; > + int ret; > + > + cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL); > + if (!cdns_phy) > + return -ENOMEM; > + > + dev_set_drvdata(dev, cdns_phy); > + cdns_phy->dev = dev; > + mutex_init(&cdns_phy->mbox_mutex); > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) > + return -ENODEV; > + cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res)); > + if (IS_ERR(cdns_phy->regs)) > + return PTR_ERR(cdns_phy->regs); > + > + phy = devm_phy_create(dev, node, &cdns_hdptx_dp_phy_ops); > + if (IS_ERR(phy)) > + return PTR_ERR(phy); > + > + phy->attrs.mode = PHY_MODE_DP; > + cdns_phy->phy = phy; > + phy_set_drvdata(phy, cdns_phy); > + > + ret = hdptx_dp_clk_enable(cdns_phy); > + if (ret) { > + dev_err(dev, "Init clk fail\n"); > + return -EINVAL; > + } > + > + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); > + if (IS_ERR(phy_provider)) { > + ret = PTR_ERR(phy_provider); > + goto clk_disable; > + } > + > + return 0; > + > +clk_disable: > + hdptx_dp_clk_disable(cdns_phy); > + > + return -EINVAL; > +} > + > +static int cdns_hdptx_dp_phy_remove(struct platform_device *pdev) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = platform_get_drvdata(pdev); > + > + hdptx_dp_clk_disable(cdns_phy); > + > + return 0; > +} > + > +static const struct of_device_id cdns_hdptx_dp_phy_of_match[] = { > + {.compatible = "fsl,imx8mq-dp-phy" }, > + { /* sentinel */ } > +}; > +MODULE_DEVICE_TABLE(of, cdns_hdptx_dp_phy_of_match); > + > +static struct platform_driver cdns_hdptx_dp_phy_driver = { > + .probe = cdns_hdptx_dp_phy_probe, > + .remove = cdns_hdptx_dp_phy_remove, > + .driver = { > + .name = "cdns-hdptx-dp-phy", > + .of_match_table = cdns_hdptx_dp_phy_of_match, > + } > +}; > +module_platform_driver(cdns_hdptx_dp_phy_driver); > + > +MODULE_AUTHOR("Sandor Yu "); > +MODULE_DESCRIPTION("Cadence HDP-TX DisplayPort PHY driver"); > +MODULE_LICENSE("GPL"); > -- > 2.34.1 -- ~Vinod From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C46F8C0015E for ; Mon, 24 Jul 2023 10:51:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0EC2E10E2D6; Mon, 24 Jul 2023 10:51:55 +0000 (UTC) Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by gabe.freedesktop.org (Postfix) with ESMTPS id A54C110E2D4 for ; Mon, 24 Jul 2023 10:51:51 +0000 (UTC) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 13E276103C; Mon, 24 Jul 2023 10:51:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C40AC433C7; Mon, 24 Jul 2023 10:51:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690195910; bh=Hm4KpRgolrbkVpbCQNLJbZKNI2aGi1klArYlS2xQMGM=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=dU8zYDo5/5EjJOeprdTvhp9BX+oIjNaKE4W+cYWvjy7w2i1Ufqbg+q58mQ6Zakowq sYA0K5Jtn0l7k/RKfSt+IIhdw9weUbjGdkYa7XeHQ3ZozEaUzvJb/dmGu1EcdUD91y 92vTj/gJyZImKETv1DlDpmgsb2GvyceIpNOA2dPQxuIk83Q+o6HYcfjqLJarNxbNZD d5YeZHkTHIyfaGUP9dPvkikLFWXe2pbydbf9grdJvggd/7J6lu7nQ1Nu7HIKDs1ZNw X7ooUtyvsZbQ6s9rJROEoFPQPbPUBNXLGbfdhBc8akMNGjezhTDym2huLL7PBcCx9c z7pkm7C2RszZw== Date: Mon, 24 Jul 2023 16:21:45 +0530 From: Vinod Koul To: Sandor Yu Subject: Re: [PATCH v7 6/7] phy: freescale: Add DisplayPort PHY driver for i.MX8MQ Message-ID: References: <50f342972001f079a0946f7718c6e3fa6aed9503.1689580812.git.Sandor.yu@nxp.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <50f342972001f079a0946f7718c6e3fa6aed9503.1689580812.git.Sandor.yu@nxp.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: andrzej.hajda@intel.com, alexander.stein@ew.tq-group.com, dri-devel@lists.freedesktop.org, Laurent.pinchart@ideasonboard.com, krzysztof.kozlowski+dt@linaro.org, linux-phy@lists.infradead.org, sam@ravnborg.org, jernej.skrabec@gmail.com, linux-imx@nxp.com, devicetree@vger.kernel.org, kernel@pengutronix.de, jonas@kwiboo.se, s.hauer@pengutronix.de, robh+dt@kernel.org, linux-arm-kernel@lists.infradead.org, oliver.brown@nxp.com, neil.armstrong@linaro.org, linux-kernel@vger.kernel.org, shawnguo@kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" On 17-07-23, 16:03, Sandor Yu wrote: > Add Cadence HDP-TX DisplayPort PHY driver for i.MX8MQ > > Cadence HDP-TX PHY could be put in either DP mode or > HDMI mode base on the configuration chosen. > DisplayPort PHY mode is configurated in the driver. > > Signed-off-by: Sandor Yu > --- > drivers/phy/freescale/Kconfig | 9 + > drivers/phy/freescale/Makefile | 1 + > drivers/phy/freescale/phy-fsl-imx8mq-dp.c | 698 ++++++++++++++++++++++ > 3 files changed, 708 insertions(+) > create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-dp.c > > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig > index 853958fb2c06..2999ba1e57d0 100644 > --- a/drivers/phy/freescale/Kconfig > +++ b/drivers/phy/freescale/Kconfig > @@ -35,6 +35,15 @@ config PHY_FSL_IMX8M_PCIE > Enable this to add support for the PCIE PHY as found on > i.MX8M family of SOCs. > > +config PHY_FSL_IMX8MQ_DP_PHY > + tristate "Freescale i.MX8MQ DP PHY support" > + depends on OF && HAS_IOMEM > + depends on COMMON_CLK > + select GENERIC_PHY > + help > + Enable this to support the Cadence HDPTX DP PHY driver > + on i.MX8MQ SOC. > + > endif > > config PHY_FSL_LYNX_28G > diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile > index cedb328bc4d2..915a429d9fbc 100644 > --- a/drivers/phy/freescale/Makefile > +++ b/drivers/phy/freescale/Makefile > @@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY) += phy-fsl-imx8qm-lvds-phy.o > obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY) += phy-fsl-imx8-mipi-dphy.o > obj-$(CONFIG_PHY_FSL_IMX8M_PCIE) += phy-fsl-imx8m-pcie.o > obj-$(CONFIG_PHY_FSL_LYNX_28G) += phy-fsl-lynx-28g.o > +obj-$(CONFIG_PHY_FSL_IMX8MQ_DP_PHY) += phy-fsl-imx8mq-dp.o > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-dp.c b/drivers/phy/freescale/phy-fsl-imx8mq-dp.c > new file mode 100644 > index 000000000000..415273ac6aa5 > --- /dev/null > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-dp.c > @@ -0,0 +1,698 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Cadence HDP-TX Display Port Interface (DP) PHY driver > + * > + * Copyright (C) 2022 NXP Semiconductor, Inc. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#define ADDR_PHY_AFE 0x80000 > + > +/* PHY registers */ > +#define CMN_SSM_BIAS_TMR 0x0022 > +#define CMN_PLLSM0_PLLEN_TMR 0x0029 > +#define CMN_PLLSM0_PLLPRE_TMR 0x002a > +#define CMN_PLLSM0_PLLVREF_TMR 0x002b > +#define CMN_PLLSM0_PLLLOCK_TMR 0x002c > +#define CMN_PLLSM0_USER_DEF_CTRL 0x002f > +#define CMN_PSM_CLK_CTRL 0x0061 > +#define CMN_PLL0_VCOCAL_START 0x0081 > +#define CMN_PLL0_VCOCAL_INIT_TMR 0x0084 > +#define CMN_PLL0_VCOCAL_ITER_TMR 0x0085 > +#define CMN_PLL0_INTDIV 0x0094 > +#define CMN_PLL0_FRACDIV 0x0095 > +#define CMN_PLL0_HIGH_THR 0x0096 > +#define CMN_PLL0_DSM_DIAG 0x0097 > +#define CMN_PLL0_SS_CTRL2 0x0099 > +#define CMN_ICAL_INIT_TMR 0x00c4 > +#define CMN_ICAL_ITER_TMR 0x00c5 > +#define CMN_RXCAL_INIT_TMR 0x00d4 > +#define CMN_RXCAL_ITER_TMR 0x00d5 > +#define CMN_TXPUCAL_INIT_TMR 0x00e4 > +#define CMN_TXPUCAL_ITER_TMR 0x00e5 > +#define CMN_TXPDCAL_INIT_TMR 0x00f4 > +#define CMN_TXPDCAL_ITER_TMR 0x00f5 > +#define CMN_ICAL_ADJ_INIT_TMR 0x0102 > +#define CMN_ICAL_ADJ_ITER_TMR 0x0103 > +#define CMN_RX_ADJ_INIT_TMR 0x0106 > +#define CMN_RX_ADJ_ITER_TMR 0x0107 > +#define CMN_TXPU_ADJ_INIT_TMR 0x010a > +#define CMN_TXPU_ADJ_ITER_TMR 0x010b > +#define CMN_TXPD_ADJ_INIT_TMR 0x010e > +#define CMN_TXPD_ADJ_ITER_TMR 0x010f > +#define CMN_DIAG_PLL0_FBH_OVRD 0x01c0 > +#define CMN_DIAG_PLL0_FBL_OVRD 0x01c1 > +#define CMN_DIAG_PLL0_OVRD 0x01c2 > +#define CMN_DIAG_PLL0_TEST_MODE 0x01c4 > +#define CMN_DIAG_PLL0_V2I_TUNE 0x01c5 > +#define CMN_DIAG_PLL0_CP_TUNE 0x01c6 > +#define CMN_DIAG_PLL0_LF_PROG 0x01c7 > +#define CMN_DIAG_PLL0_PTATIS_TUNE1 0x01c8 > +#define CMN_DIAG_PLL0_PTATIS_TUNE2 0x01c9 > +#define CMN_DIAG_HSCLK_SEL 0x01e0 > +#define CMN_DIAG_PER_CAL_ADJ 0x01ec > +#define CMN_DIAG_CAL_CTRL 0x01ed > +#define CMN_DIAG_ACYA 0x01ff > +#define XCVR_PSM_RCTRL 0x4001 > +#define XCVR_PSM_CAL_TMR 0x4002 > +#define XCVR_PSM_A0IN_TMR 0x4003 > +#define TX_TXCC_CAL_SCLR_MULT_0 0x4047 > +#define TX_TXCC_CPOST_MULT_00_0 0x404c > +#define XCVR_DIAG_PLLDRC_CTRL 0x40e0 > +#define XCVR_DIAG_PLLDRC_CTRL 0x40e0 > +#define XCVR_DIAG_HSCLK_SEL 0x40e1 > +#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40f2 > +#define TX_PSC_A0 0x4100 > +#define TX_PSC_A1 0x4101 > +#define TX_PSC_A2 0x4102 > +#define TX_PSC_A3 0x4103 > +#define TX_RCVDET_EN_TMR 0x4122 > +#define TX_RCVDET_ST_TMR 0x4123 > +#define TX_DIAG_BGREF_PREDRV_DELAY 0x41e7 > +#define TX_DIAG_BGREF_PREDRV_DELAY 0x41e7 > +#define TX_DIAG_ACYA_0 0x41ff > +#define TX_DIAG_ACYA_1 0x43ff > +#define TX_DIAG_ACYA_2 0x45ff > +#define TX_DIAG_ACYA_3 0x47ff > +#define TX_ANA_CTRL_REG_1 0x5020 > +#define TX_ANA_CTRL_REG_2 0x5021 > +#define TX_DIG_CTRL_REG_1 0x5023 > +#define TX_DIG_CTRL_REG_2 0x5024 > +#define TXDA_CYA_AUXDA_CYA 0x5025 > +#define TX_ANA_CTRL_REG_3 0x5026 > +#define TX_ANA_CTRL_REG_4 0x5027 > +#define TX_ANA_CTRL_REG_5 0x5029 > +#define RX_PSC_A0 0x8000 > +#define RX_PSC_CAL 0x8006 > +#define PHY_HDP_MODE_CTRL 0xc008 > +#define PHY_HDP_CLK_CTL 0xc009 > +#define PHY_PMA_CMN_CTRL1 0xc800 > + > +#define REF_CLK_27MHZ 27000000 > + > +enum dp_link_rate { > + RATE_1_6 = 162000, > + RATE_2_1 = 216000, > + RATE_2_4 = 243000, > + RATE_2_7 = 270000, > + RATE_3_2 = 324000, > + RATE_4_3 = 432000, > + RATE_5_4 = 540000, > + RATE_8_1 = 810000, > +}; > + > +#define MAX_LINK_RATE RATE_5_4 > + > +struct phy_pll_reg { > + u16 val[7]; > + u32 addr; > +}; > + > +static const struct phy_pll_reg phy_pll_27m_cfg[] = { > + /* 1.62 2.16 2.43 2.7 3.24 4.32 5.4 register address */ > + {{ 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e }, CMN_PLL0_VCOCAL_INIT_TMR }, > + {{ 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b }, CMN_PLL0_VCOCAL_ITER_TMR }, > + {{ 0x30b9, 0x3087, 0x3096, 0x30b4, 0x30b9, 0x3087, 0x30b4 }, CMN_PLL0_VCOCAL_START }, > + {{ 0x0077, 0x009f, 0x00b3, 0x00c7, 0x0077, 0x009f, 0x00c7 }, CMN_PLL0_INTDIV }, > + {{ 0xf9da, 0xf7cd, 0xf6c7, 0xf5c1, 0xf9da, 0xf7cd, 0xf5c1 }, CMN_PLL0_FRACDIV }, > + {{ 0x001e, 0x0028, 0x002d, 0x0032, 0x001e, 0x0028, 0x0032 }, CMN_PLL0_HIGH_THR }, > + {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_PLL0_DSM_DIAG }, > + {{ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000 }, CMN_PLLSM0_USER_DEF_CTRL }, > + {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_OVRD }, > + {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBH_OVRD }, > + {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBL_OVRD }, > + {{ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007 }, CMN_DIAG_PLL0_V2I_TUNE }, > + {{ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042 }, CMN_DIAG_PLL0_CP_TUNE }, > + {{ 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008 }, CMN_DIAG_PLL0_LF_PROG }, > + {{ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE1 }, > + {{ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE2 }, > + {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_DIAG_PLL0_TEST_MODE}, > + {{ 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016 }, CMN_PSM_CLK_CTRL } > +}; > + > +struct cdns_hdptx_dp_phy { > + void __iomem *regs; /* DPTX registers base */ > + struct device *dev; > + struct phy *phy; > + struct mutex mbox_mutex; /* mutex to protect mailbox */ > + struct clk *ref_clk, *apb_clk; > + u32 ref_clk_rate; > + u32 num_lanes; > + u32 link_rate; > + bool power_up; > +}; > + > +static int cdns_phy_reg_write(struct cdns_hdptx_dp_phy *cdns_phy, u32 addr, u32 val) > +{ > + return cdns_mhdp_reg_write(cdns_phy, ADDR_PHY_AFE + (addr << 2), val); > +} > + > +static u32 cdns_phy_reg_read(struct cdns_hdptx_dp_phy *cdns_phy, u32 addr) > +{ > + u32 reg32; > + > + cdns_mhdp_reg_read(cdns_phy, ADDR_PHY_AFE + (addr << 2), ®32); > + return reg32; > +} > + > +static int link_rate_index(u32 rate) > +{ > + switch (rate) { > + case RATE_1_6: > + return 0; > + case RATE_2_1: > + return 1; > + case RATE_2_4: > + return 2; > + case RATE_2_7: > + return 3; > + case RATE_3_2: > + return 4; > + case RATE_4_3: > + return 5; > + case RATE_5_4: > + return 6; > + default: > + return -1; > + } > +} > + > +static int hdptx_dp_clk_enable(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + struct device *dev = cdns_phy->dev; > + u32 ref_clk_rate; > + int ret; > + > + cdns_phy->ref_clk = devm_clk_get(dev, "ref"); > + if (IS_ERR(cdns_phy->ref_clk)) { > + dev_err(dev, "phy ref clock not found\n"); > + return PTR_ERR(cdns_phy->ref_clk); > + } > + > + cdns_phy->apb_clk = devm_clk_get(dev, "apb"); > + if (IS_ERR(cdns_phy->apb_clk)) { > + dev_err(dev, "phy apb clock not found\n"); > + return PTR_ERR(cdns_phy->apb_clk); > + } > + > + ret = clk_prepare_enable(cdns_phy->ref_clk); > + if (ret) { > + dev_err(cdns_phy->dev, "Failed to prepare ref clock\n"); > + return ret; > + } > + > + ref_clk_rate = clk_get_rate(cdns_phy->ref_clk); > + if (!ref_clk_rate) { > + dev_err(cdns_phy->dev, "Failed to get ref clock rate\n"); > + goto err_ref_clk; > + } > + > + if (ref_clk_rate == REF_CLK_27MHZ) { > + cdns_phy->ref_clk_rate = ref_clk_rate; > + } else { > + dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate); > + goto err_ref_clk; > + } > + > + ret = clk_prepare_enable(cdns_phy->apb_clk); > + if (ret) { > + dev_err(cdns_phy->dev, "Failed to prepare apb clock\n"); > + goto err_ref_clk; > + } > + > + return 0; > + > +err_ref_clk: > + clk_disable_unprepare(cdns_phy->ref_clk); > + return -EINVAL; > +} > + > +static void hdptx_dp_clk_disable(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + clk_disable_unprepare(cdns_phy->ref_clk); > + clk_disable_unprepare(cdns_phy->apb_clk); > +} > + > +static void hdptx_dp_aux_cfg(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + /* Power up Aux */ > + cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 1); > + > + cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_1, 0x3); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, 36); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa018); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0000); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x1001); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa098); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa198); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d); > + ndelay(150); > + cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f); > +} > + > +/* PMA common configuration for 27MHz */ > +static void hdptx_dp_phy_pma_cmn_cfg_27mhz(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u32 num_lanes = cdns_phy->num_lanes; > + u16 val; > + int k; > + > + val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); > + val &= 0xfff7; > + val |= 0x0008; magic numbers? also pls use FIELD_PRE() to set bitfields > + cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); > + > + /* Startup state machine registers */ > + cdns_phy_reg_write(cdns_phy, CMN_SSM_BIAS_TMR, 0x0087); > + cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLEN_TMR, 0x001b); > + cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLPRE_TMR, 0x0036); > + cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLVREF_TMR, 0x001b); > + cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLLOCK_TMR, 0x006c); > + > + /* Current calibration registers */ > + cdns_phy_reg_write(cdns_phy, CMN_ICAL_INIT_TMR, 0x0044); > + cdns_phy_reg_write(cdns_phy, CMN_ICAL_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_ITER_TMR, 0x0006); > + > + /* Resistor calibration registers */ > + cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_RXCAL_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_RXCAL_ITER_TMR, 0x0006); > + cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_INIT_TMR, 0x0022); > + cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_ITER_TMR, 0x0006); > + > + for (k = 0; k < num_lanes; k = k + 1) { > + /* Power state machine registers */ > + cdns_phy_reg_write(cdns_phy, XCVR_PSM_CAL_TMR | (k << 9), 0x016d); > + cdns_phy_reg_write(cdns_phy, XCVR_PSM_A0IN_TMR | (k << 9), 0x016d); > + /* Transceiver control and diagnostic registers */ > + cdns_phy_reg_write(cdns_phy, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x00a2); > + cdns_phy_reg_write(cdns_phy, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9), 0x0097); > + /* Transmitter receiver detect registers */ > + cdns_phy_reg_write(cdns_phy, TX_RCVDET_EN_TMR | (k << 9), 0x0a8c); > + cdns_phy_reg_write(cdns_phy, TX_RCVDET_ST_TMR | (k << 9), 0x0036); > + } > + > + cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1); > + cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1); > + cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1); > + cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1); > +} > + > +static void hdptx_dp_phy_pma_cmn_pll0_27mhz(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u32 num_lanes = cdns_phy->num_lanes; > + u32 link_rate = cdns_phy->link_rate; > + u16 val; > + int index, i, k; > + > + /* DP PLL data rate 0/1 clock divider value */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val &= 0x00ff; > + if (link_rate <= RATE_2_7) > + val |= 0x2400; > + else > + val |= 0x1200; more magic? > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + > + /* High speed clock 0/1 div */ > + val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL); > + val &= 0xffcc; and here > + if (link_rate <= RATE_2_7) > + val |= 0x0011; > + cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val); > + > + for (k = 0; k < num_lanes; k++) { > + val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9))); > + val = val & 0xcfff; > + if (link_rate <= RATE_2_7) > + val |= 0x1000; > + cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val); > + } > + > + /* DP PHY PLL 27MHz configuration */ > + index = link_rate_index(link_rate); > + for (i = 0; i < ARRAY_SIZE(phy_pll_27m_cfg); i++) > + cdns_phy_reg_write(cdns_phy, phy_pll_27m_cfg[i].addr, > + phy_pll_27m_cfg[i].val[index]); > + > + /* Transceiver control and diagnostic registers */ > + for (k = 0; k < num_lanes; k++) { > + val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9))); > + val = val & 0x8fff; > + if (link_rate <= RATE_2_7) > + val |= 0x2000; > + else > + val |= 0x1000; > + cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val); > + } > + > + for (k = 0; k < num_lanes; k = k + 1) { > + /* Power state machine registers */ > + cdns_phy_reg_write(cdns_phy, (XCVR_PSM_RCTRL | (k << 9)), 0xbefc); > + cdns_phy_reg_write(cdns_phy, (TX_PSC_A0 | (k << 9)), 0x6799); > + cdns_phy_reg_write(cdns_phy, (TX_PSC_A1 | (k << 9)), 0x6798); > + cdns_phy_reg_write(cdns_phy, (TX_PSC_A2 | (k << 9)), 0x0098); > + cdns_phy_reg_write(cdns_phy, (TX_PSC_A3 | (k << 9)), 0x0098); > + /* Receiver calibration power state definition register */ > + val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9)); > + val &= 0xffbb; > + cdns_phy_reg_write(cdns_phy, (RX_PSC_CAL | (k << 9)), val); > + val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9)); > + val &= 0xffbb; > + cdns_phy_reg_write(cdns_phy, (RX_PSC_A0 | (k << 9)), val); > + } > +} > + > +static void hdptx_dp_phy_ref_clock_type(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u32 val; > + > + val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); > + val &= 0xff8f; > + /* > + * single ended reference clock (val |= 0x0030); > + * differential clock (val |= 0x0000); > + * > + * for differential clock on the refclk_p and > + * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1 > + * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100); > + */ > + val |= 0x0030; > + cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); > +} > + > +static int hdptx_dp_phy_power_up(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u32 val, i; > + > + /* Enable HDP PLL’s for high speed clocks */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val |= (1 << 0); > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + /* Wait for PLL ready ACK */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + if (val & (1 << 1)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait PLL Ack failed\n"); > + return -1; > + } > + > + /* Enable HDP PLL’s data rate and full rate clocks out of PMA. */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val |= (1 << 2); > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + /* Wait for PLL clock enable ACK */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + if (val & (1 << 3)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait PLL clock enable ACk failed\n"); > + return -1; > + } > + > + /* Configure PHY in A2 Mode */ > + cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, 0x0004); > + /* Wait for Power State A2 Ack */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL); > + if (val & (1 << 6)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait A2 Ack failed\n"); > + return -1; > + } > + > + /* Configure PHY in A0 mode (PHY must be in the A0 power > + * state in order to transmit data) > + */ > + cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, 0x0101); > + > + /* Wait for Power State A0 Ack */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL); > + if (val & (1 << 4)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait A0 Ack failed\n"); > + return -1; > + } > + > + cdns_phy->power_up = true; > + > + return 0; > +} > + > +static void hdptx_dp_phy_power_down(struct cdns_hdptx_dp_phy *cdns_phy) > +{ > + u16 val; > + int i; > + > + if (!cdns_phy->power_up) > + return; > + > + /* Place the PHY lanes in the A3 power state. */ > + cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, 0x8); > + /* Wait for Power State A3 Ack */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL); > + if (val & (1 << 7)) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait A3 Ack failed\n"); > + return; > + } > + > + /* Disable HDP PLL’s data rate and full rate clocks out of PMA. */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val &= ~(1 << 2); > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + /* Wait for PLL clock gate ACK */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + if (!(val & (1 << 3))) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait PLL clock gate Ack failed\n"); > + return; > + } > + > + /* Disable HDP PLL’s for high speed clocks */ > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + val &= ~(1 << 0); > + cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); > + /* Wait for PLL disable ACK */ > + for (i = 0; i < 10; i++) { > + val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); > + if (!(val & (1 << 1))) > + break; > + msleep(20); > + } > + if (i == 10) { > + dev_err(cdns_phy->dev, "Wait PLL disable Ack failed\n"); > + return; > + } > +} > + > +static int cdns_hdptx_dp_phy_on(struct phy *phy) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy); > + > + return hdptx_dp_phy_power_up(cdns_phy); > +} > + > +static int cdns_hdptx_dp_phy_off(struct phy *phy) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy); > + > + hdptx_dp_phy_power_down(cdns_phy); > + > + return 0; > +} > + > +static int cdns_hdptx_dp_phy_init(struct phy *phy) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy); > + int ret; > + > + hdptx_dp_phy_ref_clock_type(cdns_phy); > + > + /* PHY power up */ > + ret = hdptx_dp_phy_power_up(cdns_phy); > + if (ret < 0) > + return ret; > + > + hdptx_dp_aux_cfg(cdns_phy); > + > + return ret; > +} > + > +static int cdns_hdptx_dp_configure(struct phy *phy, > + union phy_configure_opts *opts) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy); > + int ret; > + > + cdns_phy->link_rate = opts->dp.link_rate; > + cdns_phy->num_lanes = opts->dp.lanes; > + > + if (cdns_phy->link_rate > MAX_LINK_RATE) { > + dev_err(cdns_phy->dev, "Link Rate(%d) Not supported\n", cdns_phy->link_rate); > + return false; > + } > + > + /* Disable phy clock if PHY in power up state */ > + hdptx_dp_phy_power_down(cdns_phy); > + > + if (cdns_phy->ref_clk_rate == REF_CLK_27MHZ) { > + hdptx_dp_phy_pma_cmn_cfg_27mhz(cdns_phy); > + hdptx_dp_phy_pma_cmn_pll0_27mhz(cdns_phy); > + } else { > + dev_err(cdns_phy->dev, "Not support ref clock rate\n"); > + } > + > + /* PHY power up */ > + ret = hdptx_dp_phy_power_up(cdns_phy); > + > + return ret; > +} > + > +static const struct phy_ops cdns_hdptx_dp_phy_ops = { > + .init = cdns_hdptx_dp_phy_init, > + .configure = cdns_hdptx_dp_configure, > + .power_on = cdns_hdptx_dp_phy_on, > + .power_off = cdns_hdptx_dp_phy_off, > + .owner = THIS_MODULE, > +}; > + > +static int cdns_hdptx_dp_phy_probe(struct platform_device *pdev) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy; > + struct device *dev = &pdev->dev; > + struct device_node *node = dev->of_node; > + struct phy_provider *phy_provider; > + struct resource *res; > + struct phy *phy; > + int ret; > + > + cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL); > + if (!cdns_phy) > + return -ENOMEM; > + > + dev_set_drvdata(dev, cdns_phy); > + cdns_phy->dev = dev; > + mutex_init(&cdns_phy->mbox_mutex); > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) > + return -ENODEV; > + cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res)); > + if (IS_ERR(cdns_phy->regs)) > + return PTR_ERR(cdns_phy->regs); > + > + phy = devm_phy_create(dev, node, &cdns_hdptx_dp_phy_ops); > + if (IS_ERR(phy)) > + return PTR_ERR(phy); > + > + phy->attrs.mode = PHY_MODE_DP; > + cdns_phy->phy = phy; > + phy_set_drvdata(phy, cdns_phy); > + > + ret = hdptx_dp_clk_enable(cdns_phy); > + if (ret) { > + dev_err(dev, "Init clk fail\n"); > + return -EINVAL; > + } > + > + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); > + if (IS_ERR(phy_provider)) { > + ret = PTR_ERR(phy_provider); > + goto clk_disable; > + } > + > + return 0; > + > +clk_disable: > + hdptx_dp_clk_disable(cdns_phy); > + > + return -EINVAL; > +} > + > +static int cdns_hdptx_dp_phy_remove(struct platform_device *pdev) > +{ > + struct cdns_hdptx_dp_phy *cdns_phy = platform_get_drvdata(pdev); > + > + hdptx_dp_clk_disable(cdns_phy); > + > + return 0; > +} > + > +static const struct of_device_id cdns_hdptx_dp_phy_of_match[] = { > + {.compatible = "fsl,imx8mq-dp-phy" }, > + { /* sentinel */ } > +}; > +MODULE_DEVICE_TABLE(of, cdns_hdptx_dp_phy_of_match); > + > +static struct platform_driver cdns_hdptx_dp_phy_driver = { > + .probe = cdns_hdptx_dp_phy_probe, > + .remove = cdns_hdptx_dp_phy_remove, > + .driver = { > + .name = "cdns-hdptx-dp-phy", > + .of_match_table = cdns_hdptx_dp_phy_of_match, > + } > +}; > +module_platform_driver(cdns_hdptx_dp_phy_driver); > + > +MODULE_AUTHOR("Sandor Yu "); > +MODULE_DESCRIPTION("Cadence HDP-TX DisplayPort PHY driver"); > +MODULE_LICENSE("GPL"); > -- > 2.34.1 -- ~Vinod