From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from perceval.ideasonboard.com ([213.167.242.64]:47926 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726147AbeHUB3J (ORCPT ); Mon, 20 Aug 2018 21:29:09 -0400 From: Laurent Pinchart To: Laurent Pinchart Cc: dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, Jacopo Mondi , Ulrich Hecht Subject: Re: [PATCH] drm: rcar-du: Improve non-DPLL clock selection Date: Tue, 21 Aug 2018 01:12:40 +0300 Message-ID: <3773869.cu6IsclVdb@avalon> In-Reply-To: <20180820214941.22236-1-laurent.pinchart+renesas@ideasonboard.com> References: <2548120.ZfZBKIsRRX@avalon> <20180820214941.22236-1-laurent.pinchart+renesas@ideasonboard.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-renesas-soc-owner@vger.kernel.org List-ID: Hi Jacopo, On Tuesday, 21 August 2018 00:49:41 EEST Laurent Pinchart wrote: > From: Jacopo Mondi > > DU channels not equipped with a DPLL use an SoC internal (provided by > the CPG) or external clock source combined with a DU internal divider to > generate the desired output dot clock frequency. > > The current clock selection procedure does not fully exploit the ability > of external clock sources to generate the exact dot clock frequency by > themselves, but relies instead on tuning the internal DU clock divider > only, resulting in a less precise clock generation process. > > When possible, and desirable, ask the external clock source for the > exact output dot clock frequency, and select the clock source that > produces the frequency closest to the desired output dot clock. > > This patch specifically targets platforms (like Salvator-X[S] and ULCBs) > where the DU's input dotclock.in is generated by the versaclock VC5 > clock source, which is capable of generating the exact rate the DU needs > as pixel clock output. > > This patch fixes higher resolution modes which requires an high pixel > clock output currently not working on non-HDMI DU channel (such as > 1920x1080@60Hz on the VGA output). Just for the record, with this patch the following modes (as printed by modetest) on the VGA output now produce correct result with my monitor: 1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 flags: nhsync, nvsync 1600x1200 60 1600 1664 1856 2160 1200 1201 1204 1250 flags: phsync, pvsync 1360x768 60 1360 1424 1536 1792 768 771 777 795 flags: phsync, pvsync The second mode used to not display at all, with a message telling that timings were out of range, and the other two modes used to produce a displayed image partly shifted or scaled out of the screen boundaries. The following modes still produce an image partly out of the screen boundaries. 1600x900 60 1600 1624 1704 1800 900 901 904 1000 flags: phsync, pvsync 1280x960 60 1280 1376 1488 1800 960 961 964 1000 flags: phsync, pvsync 1366x768 60 1366 1436 1579 1792 768 771 774 798 flags: phsync, pvsync 1366x768 60 1366 1380 1436 1500 768 769 772 800 flags: phsync, pvsync 1280x720 60 1280 1390 1430 1650 720 725 730 750 flags: phsync, pvsync And this one is reported to be out of range. 1920x1200 60 1920 2056 2256 2592 1200 1203 1209 1245 flags: nhsync, pvsync There is thus still room for improvement (some of the issues are possibly due to my monitor though), but there's also an improvement, and no noticeable regression. > Fixes: 1b30dbde8596 ("drm: rcar-du: Add support for external pixel clock") > Signed-off-by: Jacopo Mondi > [Factor out code to a helper function] > Signed-off-by: Laurent Pinchart > --- > drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 86 ++++++++++++++++++++---------- > 1 file changed, 55 insertions(+), 31 deletions(-) > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index f8068170905a..2c9405458bbf > 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > @@ -165,6 +165,48 @@ static void rcar_du_dpll_divider(struct rcar_du_crtc > *rcrtc, best_diff); > } > > +struct du_clk_params { > + struct clk *clk; > + unsigned long rate; > + unsigned long diff; > + u32 escr; > +}; > + > +static void rcar_du_escr_divider(struct rcar_du_crtc *rcrtc, struct clk > *clk, + unsigned long target, u32 escr, > + struct du_clk_params *params) > +{ > + unsigned long rate; > + unsigned long diff; > + u32 div; > + > + /* > + * If the target rate has already been achieved perfectly we can't do > + * better. > + */ > + if (params->diff == 0) > + return; > + > + /* > + * Compute the input clock rate and internal divisor values to obtain > + * the clock rate closest to the target frequency. > + */ > + rate = clk_round_rate(clk, target); > + div = clamp(DIV_ROUND_CLOSEST(rate, target), 1UL, 64UL) - 1; > + diff = abs(rate / (div + 1) - target); > + > + /* > + * If the resulting frequency is better than any previously obtained, > + * store the parameters. > + */ > + if (diff < params->diff) { > + params->clk = clk; > + params->rate = rate; > + params->diff = diff; > + params->escr = escr | div; > + } > +} > + > static const struct soc_device_attribute rcar_du_r8a7795_es1[] = { > { .soc_id = "r8a7795", .revision = "ES1.*" }, > { /* sentinel */ } > @@ -225,42 +267,24 @@ static void rcar_du_crtc_set_display_timing(struct > rcar_du_crtc *rcrtc) > > escr = ESCR_DCLKSEL_DCLKIN | div; > } else { > - unsigned long clk; > - u32 div; > - > - /* > - * Compute the clock divisor and select the internal or external > - * dot clock based on the requested frequency. > - */ > - clk = clk_get_rate(rcrtc->clock); > - div = DIV_ROUND_CLOSEST(clk, mode_clock); > - div = clamp(div, 1U, 64U) - 1; > - > - escr = ESCR_DCLKSEL_CLKS | div; > - > - if (rcrtc->extclock) { > - unsigned long extclk; > - unsigned long extrate; > - unsigned long rate; > - u32 extdiv; > + struct du_clk_params params = { .diff = (unsigned long)-1 }; > > - extclk = clk_get_rate(rcrtc->extclock); > - extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock); > - extdiv = clamp(extdiv, 1U, 64U) - 1; > + rcar_du_escr_divider(rcrtc, rcrtc->clock, mode_clock, > + ESCR_DCLKSEL_CLKS, ¶ms); > + if (rcrtc->extclock) > + rcar_du_escr_divider(rcrtc, rcrtc->extclock, mode_clock, > + ESCR_DCLKSEL_DCLKIN, ¶ms); > > - extrate = extclk / (extdiv + 1); > - rate = clk / (div + 1); > + dev_dbg(rcrtc->group->dev->dev, "mode clock %lu %s rate %lu\n", > + mode_clock, params.clk == rcrtc->clock ? "cpg" : "ext", > + params.rate); > > - if (abs((long)extrate - (long)mode_clock) < > - abs((long)rate - (long)mode_clock)) > - escr = ESCR_DCLKSEL_DCLKIN | extdiv; > - > - dev_dbg(rcrtc->group->dev->dev, > - "mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n", > - mode_clock, extrate, rate, escr); > - } > + clk_set_rate(params.clk, params.rate); > + escr = params.escr; > } > > + dev_dbg(rcrtc->group->dev->dev, "%s: ESCR 0x%08x\n", __func__, escr); > + > rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR, > escr); > rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0); -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PATCH] drm: rcar-du: Improve non-DPLL clock selection Date: Tue, 21 Aug 2018 01:12:40 +0300 Message-ID: <3773869.cu6IsclVdb@avalon> References: <2548120.ZfZBKIsRRX@avalon> <20180820214941.22236-1-laurent.pinchart+renesas@ideasonboard.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by gabe.freedesktop.org (Postfix) with ESMTPS id 25CBB8930C for ; Mon, 20 Aug 2018 22:11:45 +0000 (UTC) In-Reply-To: <20180820214941.22236-1-laurent.pinchart+renesas@ideasonboard.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Laurent Pinchart Cc: linux-renesas-soc@vger.kernel.org, Jacopo Mondi , Ulrich Hecht , dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org SGkgSmFjb3BvLAoKT24gVHVlc2RheSwgMjEgQXVndXN0IDIwMTggMDA6NDk6NDEgRUVTVCBMYXVy ZW50IFBpbmNoYXJ0IHdyb3RlOgo+IEZyb206IEphY29wbyBNb25kaSA8amFjb3BvQGptb25kaS5v cmc+Cj4gCj4gRFUgY2hhbm5lbHMgbm90IGVxdWlwcGVkIHdpdGggYSBEUExMIHVzZSBhbiBTb0Mg aW50ZXJuYWwgKHByb3ZpZGVkIGJ5Cj4gdGhlIENQRykgb3IgZXh0ZXJuYWwgY2xvY2sgc291cmNl IGNvbWJpbmVkIHdpdGggYSBEVSBpbnRlcm5hbCBkaXZpZGVyIHRvCj4gZ2VuZXJhdGUgdGhlIGRl c2lyZWQgb3V0cHV0IGRvdCBjbG9jayBmcmVxdWVuY3kuCj4gCj4gVGhlIGN1cnJlbnQgY2xvY2sg c2VsZWN0aW9uIHByb2NlZHVyZSBkb2VzIG5vdCBmdWxseSBleHBsb2l0IHRoZSBhYmlsaXR5Cj4g b2YgZXh0ZXJuYWwgY2xvY2sgc291cmNlcyB0byBnZW5lcmF0ZSB0aGUgZXhhY3QgZG90IGNsb2Nr IGZyZXF1ZW5jeSBieQo+IHRoZW1zZWx2ZXMsIGJ1dCByZWxpZXMgaW5zdGVhZCBvbiB0dW5pbmcg dGhlIGludGVybmFsIERVIGNsb2NrIGRpdmlkZXIKPiBvbmx5LCByZXN1bHRpbmcgaW4gYSBsZXNz IHByZWNpc2UgY2xvY2sgZ2VuZXJhdGlvbiBwcm9jZXNzLgo+IAo+IFdoZW4gcG9zc2libGUsIGFu ZCBkZXNpcmFibGUsIGFzayB0aGUgZXh0ZXJuYWwgY2xvY2sgc291cmNlIGZvciB0aGUKPiBleGFj dCBvdXRwdXQgZG90IGNsb2NrIGZyZXF1ZW5jeSwgYW5kIHNlbGVjdCB0aGUgY2xvY2sgc291cmNl IHRoYXQKPiBwcm9kdWNlcyB0aGUgZnJlcXVlbmN5IGNsb3Nlc3QgdG8gdGhlIGRlc2lyZWQgb3V0 cHV0IGRvdCBjbG9jay4KPiAKPiBUaGlzIHBhdGNoIHNwZWNpZmljYWxseSB0YXJnZXRzIHBsYXRm b3JtcyAobGlrZSBTYWx2YXRvci1YW1NdIGFuZCBVTENCcykKPiB3aGVyZSB0aGUgRFUncyBpbnB1 dCBkb3RjbG9jay5pbiBpcyBnZW5lcmF0ZWQgYnkgdGhlIHZlcnNhY2xvY2sgVkM1Cj4gY2xvY2sg c291cmNlLCB3aGljaCBpcyBjYXBhYmxlIG9mIGdlbmVyYXRpbmcgdGhlIGV4YWN0IHJhdGUgdGhl IERVIG5lZWRzCj4gYXMgcGl4ZWwgY2xvY2sgb3V0cHV0Lgo+IAo+IFRoaXMgcGF0Y2ggZml4ZXMg aGlnaGVyIHJlc29sdXRpb24gbW9kZXMgd2hpY2ggcmVxdWlyZXMgYW4gaGlnaCBwaXhlbAo+IGNs b2NrIG91dHB1dCBjdXJyZW50bHkgbm90IHdvcmtpbmcgb24gbm9uLUhETUkgRFUgY2hhbm5lbCAo c3VjaCBhcwo+IDE5MjB4MTA4MEA2MEh6IG9uIHRoZSBWR0Egb3V0cHV0KS4KCkp1c3QgZm9yIHRo ZSByZWNvcmQsIHdpdGggdGhpcyBwYXRjaCB0aGUgZm9sbG93aW5nIG1vZGVzIChhcyBwcmludGVk IGJ5IAptb2RldGVzdCkgb24gdGhlIFZHQSBvdXRwdXQgbm93IHByb2R1Y2UgY29ycmVjdCByZXN1 bHQgd2l0aCBteSBtb25pdG9yOgoKICAxOTIweDEwODAgNjAgMTkyMCAyMDA4IDIwNTIgMjIwMCAx MDgwIDEwODQgMTA4OSAxMTI1IGZsYWdzOiBuaHN5bmMsIG52c3luYwogIDE2MDB4MTIwMCA2MCAx NjAwIDE2NjQgMTg1NiAyMTYwIDEyMDAgMTIwMSAxMjA0IDEyNTAgZmxhZ3M6IHBoc3luYywgcHZz eW5jCiAgMTM2MHg3NjggNjAgMTM2MCAxNDI0IDE1MzYgMTc5MiA3NjggNzcxIDc3NyA3OTUgZmxh Z3M6IHBoc3luYywgcHZzeW5jCgpUaGUgc2Vjb25kIG1vZGUgdXNlZCB0byBub3QgZGlzcGxheSBh dCBhbGwsIHdpdGggYSBtZXNzYWdlIHRlbGxpbmcgdGhhdCAKdGltaW5ncyB3ZXJlIG91dCBvZiBy YW5nZSwgYW5kIHRoZSBvdGhlciB0d28gbW9kZXMgdXNlZCB0byBwcm9kdWNlIGEgZGlzcGxheWVk IAppbWFnZSBwYXJ0bHkgc2hpZnRlZCBvciBzY2FsZWQgb3V0IG9mIHRoZSBzY3JlZW4gYm91bmRh cmllcy4KClRoZSBmb2xsb3dpbmcgbW9kZXMgc3RpbGwgcHJvZHVjZSBhbiBpbWFnZSBwYXJ0bHkg b3V0IG9mIHRoZSBzY3JlZW4gCmJvdW5kYXJpZXMuCgogIDE2MDB4OTAwIDYwIDE2MDAgMTYyNCAx NzA0IDE4MDAgOTAwIDkwMSA5MDQgMTAwMCBmbGFnczogcGhzeW5jLCBwdnN5bmMKICAxMjgweDk2 MCA2MCAxMjgwIDEzNzYgMTQ4OCAxODAwIDk2MCA5NjEgOTY0IDEwMDAgZmxhZ3M6IHBoc3luYywg cHZzeW5jCiAgMTM2Nng3NjggNjAgMTM2NiAxNDM2IDE1NzkgMTc5MiA3NjggNzcxIDc3NCA3OTgg ZmxhZ3M6IHBoc3luYywgcHZzeW5jCiAgMTM2Nng3NjggNjAgMTM2NiAxMzgwIDE0MzYgMTUwMCA3 NjggNzY5IDc3MiA4MDAgZmxhZ3M6IHBoc3luYywgcHZzeW5jCiAgMTI4MHg3MjAgNjAgMTI4MCAx MzkwIDE0MzAgMTY1MCA3MjAgNzI1IDczMCA3NTAgZmxhZ3M6IHBoc3luYywgcHZzeW5jCgpBbmQg dGhpcyBvbmUgaXMgcmVwb3J0ZWQgdG8gYmUgb3V0IG9mIHJhbmdlLgoKICAxOTIweDEyMDAgNjAg MTkyMCAyMDU2IDIyNTYgMjU5MiAxMjAwIDEyMDMgMTIwOSAxMjQ1IGZsYWdzOiBuaHN5bmMsIHB2 c3luYwoKVGhlcmUgaXMgdGh1cyBzdGlsbCByb29tIGZvciBpbXByb3ZlbWVudCAoc29tZSBvZiB0 aGUgaXNzdWVzIGFyZSBwb3NzaWJseSBkdWUgCnRvIG15IG1vbml0b3IgdGhvdWdoKSwgYnV0IHRo ZXJlJ3MgYWxzbyBhbiBpbXByb3ZlbWVudCwgYW5kIG5vIG5vdGljZWFibGUgCnJlZ3Jlc3Npb24u Cgo+IEZpeGVzOiAxYjMwZGJkZTg1OTYgKCJkcm06IHJjYXItZHU6IEFkZCBzdXBwb3J0IGZvciBl eHRlcm5hbCBwaXhlbCBjbG9jayIpCj4gU2lnbmVkLW9mZi1ieTogSmFjb3BvIE1vbmRpIDxqYWNv cG9Aam1vbmRpLm9yZz4KPiBbRmFjdG9yIG91dCBjb2RlIHRvIGEgaGVscGVyIGZ1bmN0aW9uXQo+ IFNpZ25lZC1vZmYtYnk6IExhdXJlbnQgUGluY2hhcnQgPGxhdXJlbnQucGluY2hhcnQrcmVuZXNh c0BpZGVhc29uYm9hcmQuY29tPgo+IC0tLQo+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2Fy X2R1X2NydGMuYyB8IDg2ICsrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0tLQo+ICAxIGZpbGUg Y2hhbmdlZCwgNTUgaW5zZXJ0aW9ucygrKSwgMzEgZGVsZXRpb25zKC0pCj4gCj4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfY3J0Yy5jCj4gYi9kcml2ZXJzL2dw dS9kcm0vcmNhci1kdS9yY2FyX2R1X2NydGMuYyBpbmRleCBmODA2ODE3MDkwNWEuLjJjOTQwNTQ1 OGJiZgo+IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfY3J0 Yy5jCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9jcnRjLmMKPiBAQCAt MTY1LDYgKzE2NSw0OCBAQCBzdGF0aWMgdm9pZCByY2FyX2R1X2RwbGxfZGl2aWRlcihzdHJ1Y3Qg cmNhcl9kdV9jcnRjCj4gKnJjcnRjLCBiZXN0X2RpZmYpOwo+ICB9Cj4gCj4gK3N0cnVjdCBkdV9j bGtfcGFyYW1zIHsKPiArCXN0cnVjdCBjbGsgKmNsazsKPiArCXVuc2lnbmVkIGxvbmcgcmF0ZTsK PiArCXVuc2lnbmVkIGxvbmcgZGlmZjsKPiArCXUzMiBlc2NyOwo+ICt9Owo+ICsKPiArc3RhdGlj IHZvaWQgcmNhcl9kdV9lc2NyX2RpdmlkZXIoc3RydWN0IHJjYXJfZHVfY3J0YyAqcmNydGMsIHN0 cnVjdCBjbGsKPiAqY2xrLCArCQkJCSB1bnNpZ25lZCBsb25nIHRhcmdldCwgdTMyIGVzY3IsCj4g KwkJCQkgc3RydWN0IGR1X2Nsa19wYXJhbXMgKnBhcmFtcykKPiArewo+ICsJdW5zaWduZWQgbG9u ZyByYXRlOwo+ICsJdW5zaWduZWQgbG9uZyBkaWZmOwo+ICsJdTMyIGRpdjsKPiArCj4gKwkvKgo+ ICsJICogSWYgdGhlIHRhcmdldCByYXRlIGhhcyBhbHJlYWR5IGJlZW4gYWNoaWV2ZWQgcGVyZmVj dGx5IHdlIGNhbid0IGRvCj4gKwkgKiBiZXR0ZXIuCj4gKwkgKi8KPiArCWlmIChwYXJhbXMtPmRp ZmYgPT0gMCkKPiArCQlyZXR1cm47Cj4gKwo+ICsJLyoKPiArCSAqIENvbXB1dGUgdGhlIGlucHV0 IGNsb2NrIHJhdGUgYW5kIGludGVybmFsIGRpdmlzb3IgdmFsdWVzIHRvIG9idGFpbgo+ICsJICog dGhlIGNsb2NrIHJhdGUgY2xvc2VzdCB0byB0aGUgdGFyZ2V0IGZyZXF1ZW5jeS4KPiArCSAqLwo+ ICsJcmF0ZSA9IGNsa19yb3VuZF9yYXRlKGNsaywgdGFyZ2V0KTsKPiArCWRpdiA9IGNsYW1wKERJ Vl9ST1VORF9DTE9TRVNUKHJhdGUsIHRhcmdldCksIDFVTCwgNjRVTCkgLSAxOwo+ICsJZGlmZiA9 IGFicyhyYXRlIC8gKGRpdiArIDEpIC0gdGFyZ2V0KTsKPiArCj4gKwkvKgo+ICsJICogSWYgdGhl IHJlc3VsdGluZyBmcmVxdWVuY3kgaXMgYmV0dGVyIHRoYW4gYW55IHByZXZpb3VzbHkgb2J0YWlu ZWQsCj4gKwkgKiBzdG9yZSB0aGUgcGFyYW1ldGVycy4KPiArCSAqLwo+ICsJaWYgKGRpZmYgPCBw YXJhbXMtPmRpZmYpIHsKPiArCQlwYXJhbXMtPmNsayA9IGNsazsKPiArCQlwYXJhbXMtPnJhdGUg PSByYXRlOwo+ICsJCXBhcmFtcy0+ZGlmZiA9IGRpZmY7Cj4gKwkJcGFyYW1zLT5lc2NyID0gZXNj ciB8IGRpdjsKPiArCX0KPiArfQo+ICsKPiAgc3RhdGljIGNvbnN0IHN0cnVjdCBzb2NfZGV2aWNl X2F0dHJpYnV0ZSByY2FyX2R1X3I4YTc3OTVfZXMxW10gPSB7Cj4gIAl7IC5zb2NfaWQgPSAicjhh Nzc5NSIsIC5yZXZpc2lvbiA9ICJFUzEuKiIgfSwKPiAgCXsgLyogc2VudGluZWwgKi8gfQo+IEBA IC0yMjUsNDIgKzI2NywyNCBAQCBzdGF0aWMgdm9pZCByY2FyX2R1X2NydGNfc2V0X2Rpc3BsYXlf dGltaW5nKHN0cnVjdAo+IHJjYXJfZHVfY3J0YyAqcmNydGMpCj4gCj4gIAkJZXNjciA9IEVTQ1Jf RENMS1NFTF9EQ0xLSU4gfCBkaXY7Cj4gIAl9IGVsc2Ugewo+IC0JCXVuc2lnbmVkIGxvbmcgY2xr Owo+IC0JCXUzMiBkaXY7Cj4gLQo+IC0JCS8qCj4gLQkJICogQ29tcHV0ZSB0aGUgY2xvY2sgZGl2 aXNvciBhbmQgc2VsZWN0IHRoZSBpbnRlcm5hbCBvciBleHRlcm5hbAo+IC0JCSAqIGRvdCBjbG9j ayBiYXNlZCBvbiB0aGUgcmVxdWVzdGVkIGZyZXF1ZW5jeS4KPiAtCQkgKi8KPiAtCQljbGsgPSBj bGtfZ2V0X3JhdGUocmNydGMtPmNsb2NrKTsKPiAtCQlkaXYgPSBESVZfUk9VTkRfQ0xPU0VTVChj bGssIG1vZGVfY2xvY2spOwo+IC0JCWRpdiA9IGNsYW1wKGRpdiwgMVUsIDY0VSkgLSAxOwo+IC0K PiAtCQllc2NyID0gRVNDUl9EQ0xLU0VMX0NMS1MgfCBkaXY7Cj4gLQo+IC0JCWlmIChyY3J0Yy0+ ZXh0Y2xvY2spIHsKPiAtCQkJdW5zaWduZWQgbG9uZyBleHRjbGs7Cj4gLQkJCXVuc2lnbmVkIGxv bmcgZXh0cmF0ZTsKPiAtCQkJdW5zaWduZWQgbG9uZyByYXRlOwo+IC0JCQl1MzIgZXh0ZGl2Owo+ ICsJCXN0cnVjdCBkdV9jbGtfcGFyYW1zIHBhcmFtcyA9IHsgLmRpZmYgPSAodW5zaWduZWQgbG9u ZyktMSB9Owo+IAo+IC0JCQlleHRjbGsgPSBjbGtfZ2V0X3JhdGUocmNydGMtPmV4dGNsb2NrKTsK PiAtCQkJZXh0ZGl2ID0gRElWX1JPVU5EX0NMT1NFU1QoZXh0Y2xrLCBtb2RlX2Nsb2NrKTsKPiAt CQkJZXh0ZGl2ID0gY2xhbXAoZXh0ZGl2LCAxVSwgNjRVKSAtIDE7Cj4gKwkJcmNhcl9kdV9lc2Ny X2RpdmlkZXIocmNydGMsIHJjcnRjLT5jbG9jaywgbW9kZV9jbG9jaywKPiArCQkJCSAgICAgRVND Ul9EQ0xLU0VMX0NMS1MsICZwYXJhbXMpOwo+ICsJCWlmIChyY3J0Yy0+ZXh0Y2xvY2spCj4gKwkJ CXJjYXJfZHVfZXNjcl9kaXZpZGVyKHJjcnRjLCByY3J0Yy0+ZXh0Y2xvY2ssIG1vZGVfY2xvY2ss Cj4gKwkJCQkJICAgICBFU0NSX0RDTEtTRUxfRENMS0lOLCAmcGFyYW1zKTsKPiAKPiAtCQkJZXh0 cmF0ZSA9IGV4dGNsayAvIChleHRkaXYgKyAxKTsKPiAtCQkJcmF0ZSA9IGNsayAvIChkaXYgKyAx KTsKPiArCQlkZXZfZGJnKHJjcnRjLT5ncm91cC0+ZGV2LT5kZXYsCSJtb2RlIGNsb2NrICVsdSAl cyByYXRlICVsdVxuIiwKPiArCQkJbW9kZV9jbG9jaywgcGFyYW1zLmNsayA9PSByY3J0Yy0+Y2xv Y2sgPyAiY3BnIiA6ICJleHQiLAo+ICsJCQlwYXJhbXMucmF0ZSk7Cj4gCj4gLQkJCWlmIChhYnMo KGxvbmcpZXh0cmF0ZSAtIChsb25nKW1vZGVfY2xvY2spIDwKPiAtCQkJICAgIGFicygobG9uZyly YXRlIC0gKGxvbmcpbW9kZV9jbG9jaykpCj4gLQkJCQllc2NyID0gRVNDUl9EQ0xLU0VMX0RDTEtJ TiB8IGV4dGRpdjsKPiAtCj4gLQkJCWRldl9kYmcocmNydGMtPmdyb3VwLT5kZXYtPmRldiwKPiAt CQkJCSJtb2RlIGNsb2NrICVsdSBleHRyYXRlICVsdSByYXRlICVsdSBFU0NSIDB4JTA4eFxuIiwK PiAtCQkJCW1vZGVfY2xvY2ssIGV4dHJhdGUsIHJhdGUsIGVzY3IpOwo+IC0JCX0KPiArCQljbGtf c2V0X3JhdGUocGFyYW1zLmNsaywgcGFyYW1zLnJhdGUpOwo+ICsJCWVzY3IgPSBwYXJhbXMuZXNj cjsKPiAgCX0KPiAKPiArCWRldl9kYmcocmNydGMtPmdyb3VwLT5kZXYtPmRldiwgIiVzOiBFU0NS IDB4JTA4eFxuIiwgX19mdW5jX18sIGVzY3IpOwo+ICsKPiAgCXJjYXJfZHVfZ3JvdXBfd3JpdGUo cmNydGMtPmdyb3VwLCByY3J0Yy0+aW5kZXggJSAyID8gRVNDUjIgOiBFU0NSLAo+ICAJCQkgICAg ZXNjcik7Cj4gIAlyY2FyX2R1X2dyb3VwX3dyaXRlKHJjcnRjLT5ncm91cCwgcmNydGMtPmluZGV4 ICUgMiA/IE9UQVIyIDogT1RBUiwgMCk7CgotLSAKUmVnYXJkcywKCkxhdXJlbnQgUGluY2hhcnQK CgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRl dmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8v bGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg==