From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from perceval.ideasonboard.com ([213.167.242.64]:52232 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726315AbeHUL05 (ORCPT ); Tue, 21 Aug 2018 07:26:57 -0400 From: Laurent Pinchart To: jacopo mondi Cc: Laurent Pinchart , dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, Ulrich Hecht , Kieran Bingham Subject: Re: [PATCH] drm: rcar-du: Improve non-DPLL clock selection Date: Tue, 21 Aug 2018 11:08:44 +0300 Message-ID: <2582896.I8R4H336pQ@avalon> In-Reply-To: <20180821073357.GH30122@w540> References: <2548120.ZfZBKIsRRX@avalon> <3773869.cu6IsclVdb@avalon> <20180821073357.GH30122@w540> 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, (CC'ing Kieran) On Tuesday, 21 August 2018 10:33:57 EEST jacopo mondi wrote: > On Tue, Aug 21, 2018 at 01:12:40AM +0300, Laurent Pinchart wrote: > > 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) > > I don't see the rcrtc parameter ever being used in this function. > Do you want to keep it anyhow? You're right, I'll remove it. > >> +{ > >> + 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, > > s/obtained,/obtained one,/ ? Any opinion from a native English speaker ? :-) > Will get back with some testing results on a different VGA monitor... Thank you. > >> + * store the parameters. > >> + */ > >> + if (diff < params->diff) { > >> + params->clk = clk; > >> + params->rate = rate; > >> + params->diff = diff; > >> + params->escr = escr | div; > >> + } > >> +} [snip] -- 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 11:08:44 +0300 Message-ID: <2582896.I8R4H336pQ@avalon> References: <2548120.ZfZBKIsRRX@avalon> <3773869.cu6IsclVdb@avalon> <20180821073357.GH30122@w540> 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 [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by gabe.freedesktop.org (Postfix) with ESMTPS id A82AC6E09D for ; Tue, 21 Aug 2018 08:07:49 +0000 (UTC) In-Reply-To: <20180821073357.GH30122@w540> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: jacopo mondi Cc: linux-renesas-soc@vger.kernel.org, Laurent Pinchart , Ulrich Hecht , dri-devel@lists.freedesktop.org, Kieran Bingham List-Id: dri-devel@lists.freedesktop.org SGkgSmFjb3BvLAoKKENDJ2luZyBLaWVyYW4pCgpPbiBUdWVzZGF5LCAyMSBBdWd1c3QgMjAxOCAx MDozMzo1NyBFRVNUIGphY29wbyBtb25kaSB3cm90ZToKPiBPbiBUdWUsIEF1ZyAyMSwgMjAxOCBh dCAwMToxMjo0MEFNICswMzAwLCBMYXVyZW50IFBpbmNoYXJ0IHdyb3RlOgo+ID4gT24gVHVlc2Rh eSwgMjEgQXVndXN0IDIwMTggMDA6NDk6NDEgRUVTVCBMYXVyZW50IFBpbmNoYXJ0IHdyb3RlOgo+ ID4+IEZyb206IEphY29wbyBNb25kaSA8amFjb3BvQGptb25kaS5vcmc+Cj4gPj4gCj4gPj4gRFUg Y2hhbm5lbHMgbm90IGVxdWlwcGVkIHdpdGggYSBEUExMIHVzZSBhbiBTb0MgaW50ZXJuYWwgKHBy b3ZpZGVkIGJ5Cj4gPj4gdGhlIENQRykgb3IgZXh0ZXJuYWwgY2xvY2sgc291cmNlIGNvbWJpbmVk IHdpdGggYSBEVSBpbnRlcm5hbCBkaXZpZGVyIHRvCj4gPj4gZ2VuZXJhdGUgdGhlIGRlc2lyZWQg b3V0cHV0IGRvdCBjbG9jayBmcmVxdWVuY3kuCj4gPj4gCj4gPj4gVGhlIGN1cnJlbnQgY2xvY2sg c2VsZWN0aW9uIHByb2NlZHVyZSBkb2VzIG5vdCBmdWxseSBleHBsb2l0IHRoZSBhYmlsaXR5Cj4g Pj4gb2YgZXh0ZXJuYWwgY2xvY2sgc291cmNlcyB0byBnZW5lcmF0ZSB0aGUgZXhhY3QgZG90IGNs b2NrIGZyZXF1ZW5jeSBieQo+ID4+IHRoZW1zZWx2ZXMsIGJ1dCByZWxpZXMgaW5zdGVhZCBvbiB0 dW5pbmcgdGhlIGludGVybmFsIERVIGNsb2NrIGRpdmlkZXIKPiA+PiBvbmx5LCByZXN1bHRpbmcg aW4gYSBsZXNzIHByZWNpc2UgY2xvY2sgZ2VuZXJhdGlvbiBwcm9jZXNzLgo+ID4+IAo+ID4+IFdo ZW4gcG9zc2libGUsIGFuZCBkZXNpcmFibGUsIGFzayB0aGUgZXh0ZXJuYWwgY2xvY2sgc291cmNl IGZvciB0aGUKPiA+PiBleGFjdCBvdXRwdXQgZG90IGNsb2NrIGZyZXF1ZW5jeSwgYW5kIHNlbGVj dCB0aGUgY2xvY2sgc291cmNlIHRoYXQKPiA+PiBwcm9kdWNlcyB0aGUgZnJlcXVlbmN5IGNsb3Nl c3QgdG8gdGhlIGRlc2lyZWQgb3V0cHV0IGRvdCBjbG9jay4KPiA+PiAKPiA+PiBUaGlzIHBhdGNo IHNwZWNpZmljYWxseSB0YXJnZXRzIHBsYXRmb3JtcyAobGlrZSBTYWx2YXRvci1YW1NdIGFuZCBV TENCcykKPiA+PiB3aGVyZSB0aGUgRFUncyBpbnB1dCBkb3RjbG9jay5pbiBpcyBnZW5lcmF0ZWQg YnkgdGhlIHZlcnNhY2xvY2sgVkM1Cj4gPj4gY2xvY2sgc291cmNlLCB3aGljaCBpcyBjYXBhYmxl IG9mIGdlbmVyYXRpbmcgdGhlIGV4YWN0IHJhdGUgdGhlIERVIG5lZWRzCj4gPj4gYXMgcGl4ZWwg Y2xvY2sgb3V0cHV0Lgo+ID4+IAo+ID4+IFRoaXMgcGF0Y2ggZml4ZXMgaGlnaGVyIHJlc29sdXRp b24gbW9kZXMgd2hpY2ggcmVxdWlyZXMgYW4gaGlnaCBwaXhlbAo+ID4+IGNsb2NrIG91dHB1dCBj dXJyZW50bHkgbm90IHdvcmtpbmcgb24gbm9uLUhETUkgRFUgY2hhbm5lbCAoc3VjaCBhcwo+ID4+ IDE5MjB4MTA4MEA2MEh6IG9uIHRoZSBWR0Egb3V0cHV0KS4KPiA+IAo+ID4gSnVzdCBmb3IgdGhl IHJlY29yZCwgd2l0aCB0aGlzIHBhdGNoIHRoZSBmb2xsb3dpbmcgbW9kZXMgKGFzIHByaW50ZWQg YnkKPiA+IAo+ID4gbW9kZXRlc3QpIG9uIHRoZSBWR0Egb3V0cHV0IG5vdyBwcm9kdWNlIGNvcnJl Y3QgcmVzdWx0IHdpdGggbXkgbW9uaXRvcjoKPiA+ICAgMTkyMHgxMDgwIDYwIDE5MjAgMjAwOCAy MDUyIDIyMDAgMTA4MCAxMDg0IDEwODkgMTEyNSBmbGFnczogbmhzeW5jLAo+ID4gICBudnN5bmMK PiA+ICAgMTYwMHgxMjAwIDYwIDE2MDAgMTY2NCAxODU2IDIxNjAgMTIwMCAxMjAxIDEyMDQgMTI1 MCBmbGFnczogcGhzeW5jLAo+ID4gICBwdnN5bmMKPiA+ICAgMTM2MHg3NjggNjAgMTM2MCAxNDI0 IDE1MzYgMTc5MiA3NjggNzcxIDc3NyA3OTUgZmxhZ3M6IHBoc3luYywgcHZzeW5jCj4gPiAKPiA+ IFRoZSBzZWNvbmQgbW9kZSB1c2VkIHRvIG5vdCBkaXNwbGF5IGF0IGFsbCwgd2l0aCBhIG1lc3Nh Z2UgdGVsbGluZyB0aGF0Cj4gPiB0aW1pbmdzIHdlcmUgb3V0IG9mIHJhbmdlLCBhbmQgdGhlIG90 aGVyIHR3byBtb2RlcyB1c2VkIHRvIHByb2R1Y2UgYQo+ID4gZGlzcGxheWVkIGltYWdlIHBhcnRs eSBzaGlmdGVkIG9yIHNjYWxlZCBvdXQgb2YgdGhlIHNjcmVlbiBib3VuZGFyaWVzLgo+ID4gCj4g PiBUaGUgZm9sbG93aW5nIG1vZGVzIHN0aWxsIHByb2R1Y2UgYW4gaW1hZ2UgcGFydGx5IG91dCBv ZiB0aGUgc2NyZWVuCj4gPiBib3VuZGFyaWVzLgo+ID4gCj4gPiAgIDE2MDB4OTAwIDYwIDE2MDAg MTYyNCAxNzA0IDE4MDAgOTAwIDkwMSA5MDQgMTAwMCBmbGFnczogcGhzeW5jLCBwdnN5bmMKPiA+ ICAgMTI4MHg5NjAgNjAgMTI4MCAxMzc2IDE0ODggMTgwMCA5NjAgOTYxIDk2NCAxMDAwIGZsYWdz OiBwaHN5bmMsIHB2c3luYwo+ID4gICAxMzY2eDc2OCA2MCAxMzY2IDE0MzYgMTU3OSAxNzkyIDc2 OCA3NzEgNzc0IDc5OCBmbGFnczogcGhzeW5jLCBwdnN5bmMKPiA+ICAgMTM2Nng3NjggNjAgMTM2 NiAxMzgwIDE0MzYgMTUwMCA3NjggNzY5IDc3MiA4MDAgZmxhZ3M6IHBoc3luYywgcHZzeW5jCj4g PiAgIDEyODB4NzIwIDYwIDEyODAgMTM5MCAxNDMwIDE2NTAgNzIwIDcyNSA3MzAgNzUwIGZsYWdz OiBwaHN5bmMsIHB2c3luYwo+ID4gCj4gPiBBbmQgdGhpcyBvbmUgaXMgcmVwb3J0ZWQgdG8gYmUg b3V0IG9mIHJhbmdlLgo+ID4gCj4gPiAgIDE5MjB4MTIwMCA2MCAxOTIwIDIwNTYgMjI1NiAyNTky IDEyMDAgMTIwMyAxMjA5IDEyNDUgZmxhZ3M6IG5oc3luYywKPiA+ICAgcHZzeW5jCj4gPiAKPiA+ IFRoZXJlIGlzIHRodXMgc3RpbGwgcm9vbSBmb3IgaW1wcm92ZW1lbnQgKHNvbWUgb2YgdGhlIGlz c3VlcyBhcmUgcG9zc2libHkKPiA+IGR1ZSB0byBteSBtb25pdG9yIHRob3VnaCksIGJ1dCB0aGVy ZSdzIGFsc28gYW4gaW1wcm92ZW1lbnQsIGFuZCBubwo+ID4gbm90aWNlYWJsZSByZWdyZXNzaW9u Lgo+ID4gCj4gPj4gRml4ZXM6IDFiMzBkYmRlODU5NiAoImRybTogcmNhci1kdTogQWRkIHN1cHBv cnQgZm9yIGV4dGVybmFsIHBpeGVsCj4gPj4gY2xvY2siKQo+ID4+IFNpZ25lZC1vZmYtYnk6IEph Y29wbyBNb25kaSA8amFjb3BvQGptb25kaS5vcmc+Cj4gPj4gW0ZhY3RvciBvdXQgY29kZSB0byBh IGhlbHBlciBmdW5jdGlvbl0KPiA+PiBTaWduZWQtb2ZmLWJ5OiBMYXVyZW50IFBpbmNoYXJ0Cj4g Pj4gPGxhdXJlbnQucGluY2hhcnQrcmVuZXNhc0BpZGVhc29uYm9hcmQuY29tPgo+ID4+IC0tLQo+ ID4+IAo+ID4+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2NydGMuYyB8IDg2ICsr KysrKysrKysrKysrKysrKystLS0tLS0tLS0KPiA+PiAgMSBmaWxlIGNoYW5nZWQsIDU1IGluc2Vy dGlvbnMoKyksIDMxIGRlbGV0aW9ucygtKQo+ID4+IAo+ID4+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2NydGMuYwo+ID4+IGIvZHJpdmVycy9ncHUvZHJtL3Jj YXItZHUvcmNhcl9kdV9jcnRjLmMgaW5kZXgKPiA+PiBmODA2ODE3MDkwNWEuLjJjOTQwNTQ1OGJi Zgo+ID4+IDEwMDY0NAo+ID4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVf Y3J0Yy5jCj4gPj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9jcnRjLmMK PiA+PiBAQCAtMTY1LDYgKzE2NSw0OCBAQCBzdGF0aWMgdm9pZCByY2FyX2R1X2RwbGxfZGl2aWRl cihzdHJ1Y3QKPiA+PiByY2FyX2R1X2NydGMgKnJjcnRjLAo+ID4+ICAJYmVzdF9kaWZmKTsKPiA+ PiAgfQo+ID4+IAo+ID4+ICtzdHJ1Y3QgZHVfY2xrX3BhcmFtcyB7Cj4gPj4gKwlzdHJ1Y3QgY2xr ICpjbGs7Cj4gPj4gKwl1bnNpZ25lZCBsb25nIHJhdGU7Cj4gPj4gKwl1bnNpZ25lZCBsb25nIGRp ZmY7Cj4gPj4gKwl1MzIgZXNjcjsKPiA+PiArfTsKPiA+PiArCj4gPj4gK3N0YXRpYyB2b2lkIHJj YXJfZHVfZXNjcl9kaXZpZGVyKHN0cnVjdCByY2FyX2R1X2NydGMgKnJjcnRjLCBzdHJ1Y3QgY2xr Cj4gPj4gKmNsaywKPiA+PiArCQkJCSB1bnNpZ25lZCBsb25nIHRhcmdldCwgdTMyIGVzY3IsCj4g Pj4gKwkJCQkgc3RydWN0IGR1X2Nsa19wYXJhbXMgKnBhcmFtcykKPiAKPiBJIGRvbid0IHNlZSB0 aGUgcmNydGMgcGFyYW1ldGVyIGV2ZXIgYmVpbmcgdXNlZCBpbiB0aGlzIGZ1bmN0aW9uLgo+IERv IHlvdSB3YW50IHRvIGtlZXAgaXQgYW55aG93PwoKWW91J3JlIHJpZ2h0LCBJJ2xsIHJlbW92ZSBp dC4KCj4gPj4gK3sKPiA+PiArCXVuc2lnbmVkIGxvbmcgcmF0ZTsKPiA+PiArCXVuc2lnbmVkIGxv bmcgZGlmZjsKPiA+PiArCXUzMiBkaXY7Cj4gPj4gKwo+ID4+ICsJLyoKPiA+PiArCSAqIElmIHRo ZSB0YXJnZXQgcmF0ZSBoYXMgYWxyZWFkeSBiZWVuIGFjaGlldmVkIHBlcmZlY3RseSB3ZSBjYW4n dCBkbwo+ID4+ICsJICogYmV0dGVyLgo+ID4+ICsJICovCj4gPj4gKwlpZiAocGFyYW1zLT5kaWZm ID09IDApCj4gPj4gKwkJcmV0dXJuOwo+ID4+ICsKPiA+PiArCS8qCj4gPj4gKwkgKiBDb21wdXRl IHRoZSBpbnB1dCBjbG9jayByYXRlIGFuZCBpbnRlcm5hbCBkaXZpc29yIHZhbHVlcyB0byBvYnRh aW4KPiA+PiArCSAqIHRoZSBjbG9jayByYXRlIGNsb3Nlc3QgdG8gdGhlIHRhcmdldCBmcmVxdWVu Y3kuCj4gPj4gKwkgKi8KPiA+PiArCXJhdGUgPSBjbGtfcm91bmRfcmF0ZShjbGssIHRhcmdldCk7 Cj4gPj4gKwlkaXYgPSBjbGFtcChESVZfUk9VTkRfQ0xPU0VTVChyYXRlLCB0YXJnZXQpLCAxVUws IDY0VUwpIC0gMTsKPiA+PiArCWRpZmYgPSBhYnMocmF0ZSAvIChkaXYgKyAxKSAtIHRhcmdldCk7 Cj4gPj4gKwo+ID4+ICsJLyoKPiA+PiArCSAqIElmIHRoZSByZXN1bHRpbmcgZnJlcXVlbmN5IGlz IGJldHRlciB0aGFuIGFueSBwcmV2aW91c2x5IG9idGFpbmVkLAo+IAo+IHMvb2J0YWluZWQsL29i dGFpbmVkIG9uZSwvID8KCkFueSBvcGluaW9uIGZyb20gYSBuYXRpdmUgRW5nbGlzaCBzcGVha2Vy ID8gOi0pCgo+IFdpbGwgZ2V0IGJhY2sgd2l0aCBzb21lIHRlc3RpbmcgcmVzdWx0cyBvbiBhIGRp ZmZlcmVudCBWR0EgbW9uaXRvci4uLgoKVGhhbmsgeW91LgoKPiA+PiArCSAqIHN0b3JlIHRoZSBw YXJhbWV0ZXJzLgo+ID4+ICsJICovCj4gPj4gKwlpZiAoZGlmZiA8IHBhcmFtcy0+ZGlmZikgewo+ ID4+ICsJCXBhcmFtcy0+Y2xrID0gY2xrOwo+ID4+ICsJCXBhcmFtcy0+cmF0ZSA9IHJhdGU7Cj4g Pj4gKwkJcGFyYW1zLT5kaWZmID0gZGlmZjsKPiA+PiArCQlwYXJhbXMtPmVzY3IgPSBlc2NyIHwg ZGl2Owo+ID4+ICsJfQo+ID4+ICt9Cgpbc25pcF0KCi0tIApSZWdhcmRzLAoKTGF1cmVudCBQaW5j aGFydAoKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpk cmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0 cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK