From mboxrd@z Thu Jan 1 00:00:00 1970 From: laurent.pinchart@ideasonboard.com (Laurent Pinchart) Date: Thu, 19 Oct 2017 00:16:50 +0300 Subject: [PATCH 2/2 v2] drm: bridge: Add THS8134A/B support to dumb VGA DAC In-Reply-To: <20171017101904.22308-2-linus.walleij@linaro.org> References: <20171017101904.22308-1-linus.walleij@linaro.org> <20171017101904.22308-2-linus.walleij@linaro.org> Message-ID: <1896170.2c8n16LLNB@avalon> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Linus, Thank you for the patch. On Tuesday, 17 October 2017 13:19:04 EEST Linus Walleij wrote: > This extends the dumb VGA DAC bridge to handle the THS8134A > and THS8134B VGA DACs in addition to those already handled. > > The THS8134A, THS8134B and as it turns out also THS8135 need to > have data clocked out at the negative edge of the clock pulse, > since they clock it into the DAC at the positive edge (so by > then it needs to be stable) so we need some extra logic to flag > this on the connector to the driver. > > The semantics of the flag DRM_BUS_FLAG_PIXDATA_NEGEDGE in > clearly indicates that this flag tells > when to *drive* the data, not when the receiver *reads* it, > so the TI variants needs to be handled like this. > > Introduce a variant struct and contain the information there, > and add a bit of helpful comments about how this works so > people will get it right when adding new DACs or connectiong > new display drivers to DACs. > > The fact that THS8135 might be working on some systems today > is probably due to the fact that the display driver cannot > configure when the data is clocked out and the electronics > have simply been designed around it so it works anyways. > > The phenomenon is very real on the ARM reference designs using > PL111 where the hardware can control which edge to push out > the data. > > Cc: Laurent Pinchart > Cc: Bartosz Golaszewski > Cc: Maxime Ripard > Signed-off-by: Linus Walleij > --- > ChangeLog v1->v2: > - Alphabetize includes > - Use a u32 with the bus polarity flags and just encode the > polarity using the DRM define directly. > - Rename vendor_data to vendor_info. > - Simplify assignment of the flag as it is just a simple > u32 now. > - Probe all TI variants on the "ti,ths813x" wildcard for now, > we only need to know that the device is in this family to > set the clock edge flag right. > --- > drivers/gpu/drm/bridge/dumb-vga-dac.c | 51 +++++++++++++++++++++++++++++--- > 1 file changed, 47 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c > b/drivers/gpu/drm/bridge/dumb-vga-dac.c index 831a606c4706..9cd19e4c33c9 > 100644 > --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c > +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c > @@ -11,6 +11,7 @@ > */ > > #include > +#include > #include > #include > > @@ -19,9 +20,18 @@ > #include > #include > > +/** > + * struct vga_dac_info - characteristics of the DAC > + * @clk_edge_latch: this defines the clock edge latch for the variant > + */ > +struct vga_dac_info { > + u32 clk_edge_latch; > +}; > + > struct dumb_vga { > struct drm_bridge bridge; > struct drm_connector connector; > + struct vga_dac_info const *variant; Anything wrong with the usual order of keywords (const struct vga_dac_info *variant) ? > struct i2c_adapter *ddc; > struct regulator *vdd; > @@ -55,7 +65,9 @@ static int dumb_vga_get_modes(struct drm_connector > *connector) } > > drm_mode_connector_update_edid_property(connector, edid); > - return drm_add_edid_modes(connector, edid); > + ret = drm_add_edid_modes(connector, edid); > + connector->display_info.bus_flags |= vga->variant->clk_edge_latch; As far as I can tell drm_add_edid_modes() doesn't set bus_flags, so you could keep the return live as-is and set the clock edge flag just before it. > + return ret; > > fallback: > /* > @@ -67,6 +79,8 @@ static int dumb_vga_get_modes(struct drm_connector > *connector) /* And prefer a mode pretty much anyone can handle */ > drm_set_preferred_mode(connector, 1024, 768); > > + connector->display_info.bus_flags |= vga->variant->clk_edge_latch; > + > return ret; > } > > @@ -183,6 +197,7 @@ static int dumb_vga_probe(struct platform_device *pdev) > if (!vga) > return -ENOMEM; > platform_set_drvdata(pdev, vga); > + vga->variant = of_device_get_match_data(&pdev->dev); > > vga->vdd = devm_regulator_get_optional(&pdev->dev, "vdd"); > if (IS_ERR(vga->vdd)) { > @@ -226,10 +241,38 @@ static int dumb_vga_remove(struct platform_device > *pdev) return 0; > } > > +static const struct vga_dac_info default_dac_variant = { > + /* > + * These DACs read data on the negative edge. For example in the > + * ADV7123 datasheet (revision D, page 8) there is a timing diagram > + * making this clear. So consequently we need to latch the data > + * on the positive edge. > + */ > + .clk_edge_latch = DRM_BUS_FLAG_PIXDATA_POSEDGE, > +}; > + > +static const struct vga_dac_info ti_ths_dac_variant = { > + /* > + * The TI DACs read the data on the positive edge of the CLK, > + * so consequently we need to latch the data on the negative > + * edge. > + */ > + .clk_edge_latch = DRM_BUS_FLAG_PIXDATA_NEGEDGE, > +}; > + > static const struct of_device_id dumb_vga_match[] = { > - { .compatible = "dumb-vga-dac" }, > - { .compatible = "adi,adv7123" }, > - { .compatible = "ti,ths8135" }, You need to keep support for this compatible string for backward compatibility. > + { > + .compatible = "dumb-vga-dac", > + .data = &default_dac_variant, > + }, > + { > + .compatible = "adi,adv7123", > + .data = &default_dac_variant, > + }, > + { > + .compatible = "ti,ths813x", > + .data = &ti_ths_dac_variant, > + }, > {}, > }; > MODULE_DEVICE_TABLE(of, dumb_vga_match); -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PATCH 2/2 v2] drm: bridge: Add THS8134A/B support to dumb VGA DAC Date: Thu, 19 Oct 2017 00:16:50 +0300 Message-ID: <1896170.2c8n16LLNB@avalon> References: <20171017101904.22308-1-linus.walleij@linaro.org> <20171017101904.22308-2-linus.walleij@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from galahad.ideasonboard.com (galahad.ideasonboard.com [185.26.127.97]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9B68F6E249 for ; Wed, 18 Oct 2017 21:16:30 +0000 (UTC) In-Reply-To: <20171017101904.22308-2-linus.walleij@linaro.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Linus Walleij Cc: Laurent Pinchart , Bartosz Golaszewski , dri-devel@lists.freedesktop.org, Maxime Ripard , linux-arm-kernel@lists.infradead.org List-Id: dri-devel@lists.freedesktop.org SGkgTGludXMsCgpUaGFuayB5b3UgZm9yIHRoZSBwYXRjaC4KCk9uIFR1ZXNkYXksIDE3IE9jdG9i ZXIgMjAxNyAxMzoxOTowNCBFRVNUIExpbnVzIFdhbGxlaWogd3JvdGU6Cj4gVGhpcyBleHRlbmRz IHRoZSBkdW1iIFZHQSBEQUMgYnJpZGdlIHRvIGhhbmRsZSB0aGUgVEhTODEzNEEKPiBhbmQgVEhT ODEzNEIgVkdBIERBQ3MgaW4gYWRkaXRpb24gdG8gdGhvc2UgYWxyZWFkeSBoYW5kbGVkLgo+IAo+ IFRoZSBUSFM4MTM0QSwgVEhTODEzNEIgYW5kIGFzIGl0IHR1cm5zIG91dCBhbHNvIFRIUzgxMzUg bmVlZCB0bwo+IGhhdmUgZGF0YSBjbG9ja2VkIG91dCBhdCB0aGUgbmVnYXRpdmUgZWRnZSBvZiB0 aGUgY2xvY2sgcHVsc2UsCj4gc2luY2UgdGhleSBjbG9jayBpdCBpbnRvIHRoZSBEQUMgYXQgdGhl IHBvc2l0aXZlIGVkZ2UgKHNvIGJ5Cj4gdGhlbiBpdCBuZWVkcyB0byBiZSBzdGFibGUpIHNvIHdl IG5lZWQgc29tZSBleHRyYSBsb2dpYyB0byBmbGFnCj4gdGhpcyBvbiB0aGUgY29ubmVjdG9yIHRv IHRoZSBkcml2ZXIuCj4gCj4gVGhlIHNlbWFudGljcyBvZiB0aGUgZmxhZyBEUk1fQlVTX0ZMQUdf UElYREFUQV9ORUdFREdFIGluCj4gPGRybS9kcm1fY29ubmVjdG9yLmg+IGNsZWFybHkgaW5kaWNh dGVzIHRoYXQgdGhpcyBmbGFnIHRlbGxzCj4gd2hlbiB0byAqZHJpdmUqIHRoZSBkYXRhLCBub3Qg d2hlbiB0aGUgcmVjZWl2ZXIgKnJlYWRzKiBpdCwKPiBzbyB0aGUgVEkgdmFyaWFudHMgbmVlZHMg dG8gYmUgaGFuZGxlZCBsaWtlIHRoaXMuCj4gCj4gSW50cm9kdWNlIGEgdmFyaWFudCBzdHJ1Y3Qg YW5kIGNvbnRhaW4gdGhlIGluZm9ybWF0aW9uIHRoZXJlLAo+IGFuZCBhZGQgYSBiaXQgb2YgaGVs cGZ1bCBjb21tZW50cyBhYm91dCBob3cgdGhpcyB3b3JrcyBzbwo+IHBlb3BsZSB3aWxsIGdldCBp dCByaWdodCB3aGVuIGFkZGluZyBuZXcgREFDcyBvciBjb25uZWN0aW9uZwo+IG5ldyBkaXNwbGF5 IGRyaXZlcnMgdG8gREFDcy4KPiAKPiBUaGUgZmFjdCB0aGF0IFRIUzgxMzUgbWlnaHQgYmUgd29y a2luZyBvbiBzb21lIHN5c3RlbXMgdG9kYXkKPiBpcyBwcm9iYWJseSBkdWUgdG8gdGhlIGZhY3Qg dGhhdCB0aGUgZGlzcGxheSBkcml2ZXIgY2Fubm90Cj4gY29uZmlndXJlIHdoZW4gdGhlIGRhdGEg aXMgY2xvY2tlZCBvdXQgYW5kIHRoZSBlbGVjdHJvbmljcwo+IGhhdmUgc2ltcGx5IGJlZW4gZGVz aWduZWQgYXJvdW5kIGl0IHNvIGl0IHdvcmtzIGFueXdheXMuCj4gCj4gVGhlIHBoZW5vbWVub24g aXMgdmVyeSByZWFsIG9uIHRoZSBBUk0gcmVmZXJlbmNlIGRlc2lnbnMgdXNpbmcKPiBQTDExMSB3 aGVyZSB0aGUgaGFyZHdhcmUgY2FuIGNvbnRyb2wgd2hpY2ggZWRnZSB0byBwdXNoIG91dAo+IHRo ZSBkYXRhLgo+IAo+IENjOiBMYXVyZW50IFBpbmNoYXJ0IDxsYXVyZW50LnBpbmNoYXJ0K3JlbmVz YXNAaWRlYXNvbmJvYXJkLmNvbT4KPiBDYzogQmFydG9zeiBHb2xhc3pld3NraSA8YmdvbGFzemV3 c2tpQGJheWxpYnJlLmNvbT4KPiBDYzogTWF4aW1lIFJpcGFyZCA8bWF4aW1lLnJpcGFyZEBmcmVl LWVsZWN0cm9ucy5jb20+Cj4gU2lnbmVkLW9mZi1ieTogTGludXMgV2FsbGVpaiA8bGludXMud2Fs bGVpakBsaW5hcm8ub3JnPgo+IC0tLQo+IENoYW5nZUxvZyB2MS0+djI6Cj4gLSBBbHBoYWJldGl6 ZSBpbmNsdWRlcwo+IC0gVXNlIGEgdTMyIHdpdGggdGhlIGJ1cyBwb2xhcml0eSBmbGFncyBhbmQg anVzdCBlbmNvZGUgdGhlCj4gICBwb2xhcml0eSB1c2luZyB0aGUgRFJNIGRlZmluZSBkaXJlY3Rs eS4KPiAtIFJlbmFtZSB2ZW5kb3JfZGF0YSB0byB2ZW5kb3JfaW5mby4KPiAtIFNpbXBsaWZ5IGFz c2lnbm1lbnQgb2YgdGhlIGZsYWcgYXMgaXQgaXMganVzdCBhIHNpbXBsZQo+ICAgdTMyIG5vdy4K PiAtIFByb2JlIGFsbCBUSSB2YXJpYW50cyBvbiB0aGUgInRpLHRoczgxM3giIHdpbGRjYXJkIGZv ciBub3csCj4gICB3ZSBvbmx5IG5lZWQgdG8ga25vdyB0aGF0IHRoZSBkZXZpY2UgaXMgaW4gdGhp cyBmYW1pbHkgdG8KPiAgIHNldCB0aGUgY2xvY2sgZWRnZSBmbGFnIHJpZ2h0Lgo+IC0tLQo+ICBk cml2ZXJzL2dwdS9kcm0vYnJpZGdlL2R1bWItdmdhLWRhYy5jIHwgNTEgKysrKysrKysrKysrKysr KysrKysrKysrKysrKystLS0KPiAgMSBmaWxlIGNoYW5nZWQsIDQ3IGluc2VydGlvbnMoKyksIDQg ZGVsZXRpb25zKC0pCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvZHVt Yi12Z2EtZGFjLmMKPiBiL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvZHVtYi12Z2EtZGFjLmMgaW5k ZXggODMxYTYwNmM0NzA2Li45Y2QxOWU0YzMzYzkKPiAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2dw dS9kcm0vYnJpZGdlL2R1bWItdmdhLWRhYy5jCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2JyaWRn ZS9kdW1iLXZnYS1kYWMuYwo+IEBAIC0xMSw2ICsxMSw3IEBACj4gICAqLwo+IAo+ICAjaW5jbHVk ZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZl9kZXZpY2UuaD4KPiAgI2lu Y2x1ZGUgPGxpbnV4L29mX2dyYXBoLmg+Cj4gICNpbmNsdWRlIDxsaW51eC9yZWd1bGF0b3IvY29u c3VtZXIuaD4KPiAKPiBAQCAtMTksOSArMjAsMTggQEAKPiAgI2luY2x1ZGUgPGRybS9kcm1fY3J0 Yy5oPgo+ICAjaW5jbHVkZSA8ZHJtL2RybV9jcnRjX2hlbHBlci5oPgo+IAo+ICsvKioKPiArICog c3RydWN0IHZnYV9kYWNfaW5mbyAtIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgREFDCj4gKyAqIEBj bGtfZWRnZV9sYXRjaDogdGhpcyBkZWZpbmVzIHRoZSBjbG9jayBlZGdlIGxhdGNoIGZvciB0aGUg dmFyaWFudAo+ICsgKi8KPiArc3RydWN0IHZnYV9kYWNfaW5mbyB7Cj4gKwl1MzIgY2xrX2VkZ2Vf bGF0Y2g7Cj4gK307Cj4gKwo+ICBzdHJ1Y3QgZHVtYl92Z2Egewo+ICAJc3RydWN0IGRybV9icmlk Z2UJYnJpZGdlOwo+ICAJc3RydWN0IGRybV9jb25uZWN0b3IJY29ubmVjdG9yOwo+ICsJc3RydWN0 IHZnYV9kYWNfaW5mbyBjb25zdCAqdmFyaWFudDsKCkFueXRoaW5nIHdyb25nIHdpdGggdGhlIHVz dWFsIG9yZGVyIG9mIGtleXdvcmRzIChjb25zdCBzdHJ1Y3QgdmdhX2RhY19pbmZvIAoqdmFyaWFu dCkgPwoKPiAgCXN0cnVjdCBpMmNfYWRhcHRlcgkqZGRjOwo+ICAJc3RydWN0IHJlZ3VsYXRvcgkq dmRkOwo+IEBAIC01NSw3ICs2NSw5IEBAIHN0YXRpYyBpbnQgZHVtYl92Z2FfZ2V0X21vZGVzKHN0 cnVjdCBkcm1fY29ubmVjdG9yCj4gKmNvbm5lY3RvcikgfQo+IAo+ICAJZHJtX21vZGVfY29ubmVj dG9yX3VwZGF0ZV9lZGlkX3Byb3BlcnR5KGNvbm5lY3RvciwgZWRpZCk7Cj4gLQlyZXR1cm4gZHJt X2FkZF9lZGlkX21vZGVzKGNvbm5lY3RvciwgZWRpZCk7Cj4gKwlyZXQgPSBkcm1fYWRkX2VkaWRf bW9kZXMoY29ubmVjdG9yLCBlZGlkKTsKPiArCWNvbm5lY3Rvci0+ZGlzcGxheV9pbmZvLmJ1c19m bGFncyB8PSB2Z2EtPnZhcmlhbnQtPmNsa19lZGdlX2xhdGNoOwoKQXMgZmFyIGFzIEkgY2FuIHRl bGwgZHJtX2FkZF9lZGlkX21vZGVzKCkgZG9lc24ndCBzZXQgYnVzX2ZsYWdzLCBzbyB5b3UgY291 bGQgCmtlZXAgdGhlIHJldHVybiBsaXZlIGFzLWlzIGFuZCBzZXQgdGhlIGNsb2NrIGVkZ2UgZmxh ZyBqdXN0IGJlZm9yZSBpdC4KCj4gKwlyZXR1cm4gcmV0Owo+IAo+ICBmYWxsYmFjazoKPiAgCS8q Cj4gQEAgLTY3LDYgKzc5LDggQEAgc3RhdGljIGludCBkdW1iX3ZnYV9nZXRfbW9kZXMoc3RydWN0 IGRybV9jb25uZWN0b3IKPiAqY29ubmVjdG9yKSAvKiBBbmQgcHJlZmVyIGEgbW9kZSBwcmV0dHkg bXVjaCBhbnlvbmUgY2FuIGhhbmRsZSAqLwo+ICAJZHJtX3NldF9wcmVmZXJyZWRfbW9kZShjb25u ZWN0b3IsIDEwMjQsIDc2OCk7Cj4gCj4gKwljb25uZWN0b3ItPmRpc3BsYXlfaW5mby5idXNfZmxh Z3MgfD0gdmdhLT52YXJpYW50LT5jbGtfZWRnZV9sYXRjaDsKPiArCj4gIAlyZXR1cm4gcmV0Owo+ ICB9Cj4gCj4gQEAgLTE4Myw2ICsxOTcsNyBAQCBzdGF0aWMgaW50IGR1bWJfdmdhX3Byb2JlKHN0 cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gIAlpZiAoIXZnYSkKPiAgCQlyZXR1cm4gLUVO T01FTTsKPiAgCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIHZnYSk7Cj4gKwl2Z2EtPnZhcmlh bnQgPSBvZl9kZXZpY2VfZ2V0X21hdGNoX2RhdGEoJnBkZXYtPmRldik7Cj4gCj4gIAl2Z2EtPnZk ZCA9IGRldm1fcmVndWxhdG9yX2dldF9vcHRpb25hbCgmcGRldi0+ZGV2LCAidmRkIik7Cj4gIAlp ZiAoSVNfRVJSKHZnYS0+dmRkKSkgewo+IEBAIC0yMjYsMTAgKzI0MSwzOCBAQCBzdGF0aWMgaW50 IGR1bWJfdmdhX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlCj4gKnBkZXYpIHJldHVybiAw Owo+ICB9Cj4gCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdmdhX2RhY19pbmZvIGRlZmF1bHRfZGFj X3ZhcmlhbnQgPSB7Cj4gKwkvKgo+ICsJICogVGhlc2UgREFDcyByZWFkIGRhdGEgb24gdGhlIG5l Z2F0aXZlIGVkZ2UuIEZvciBleGFtcGxlIGluIHRoZQo+ICsJICogQURWNzEyMyBkYXRhc2hlZXQg KHJldmlzaW9uIEQsIHBhZ2UgOCkgdGhlcmUgaXMgYSB0aW1pbmcgZGlhZ3JhbQo+ICsJICogbWFr aW5nIHRoaXMgY2xlYXIuIFNvIGNvbnNlcXVlbnRseSB3ZSBuZWVkIHRvIGxhdGNoIHRoZSBkYXRh Cj4gKwkgKiBvbiB0aGUgcG9zaXRpdmUgZWRnZS4KPiArCSAqLwo+ICsJLmNsa19lZGdlX2xhdGNo ID0gRFJNX0JVU19GTEFHX1BJWERBVEFfUE9TRURHRSwKPiArfTsKPiArCj4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgdmdhX2RhY19pbmZvIHRpX3Roc19kYWNfdmFyaWFudCA9IHsKPiArCS8qCj4gKwkg KiBUaGUgVEkgREFDcyByZWFkIHRoZSBkYXRhIG9uIHRoZSBwb3NpdGl2ZSBlZGdlIG9mIHRoZSBD TEssCj4gKwkgKiBzbyBjb25zZXF1ZW50bHkgd2UgbmVlZCB0byBsYXRjaCB0aGUgZGF0YSBvbiB0 aGUgbmVnYXRpdmUKPiArCSAqIGVkZ2UuCj4gKwkgKi8KPiArCS5jbGtfZWRnZV9sYXRjaCA9IERS TV9CVVNfRkxBR19QSVhEQVRBX05FR0VER0UsCj4gK307Cj4gKwo+ICBzdGF0aWMgY29uc3Qgc3Ry dWN0IG9mX2RldmljZV9pZCBkdW1iX3ZnYV9tYXRjaFtdID0gewo+IC0JeyAuY29tcGF0aWJsZSA9 ICJkdW1iLXZnYS1kYWMiIH0sCj4gLQl7IC5jb21wYXRpYmxlID0gImFkaSxhZHY3MTIzIiB9LAo+ IC0JeyAuY29tcGF0aWJsZSA9ICJ0aSx0aHM4MTM1IiB9LAoKWW91IG5lZWQgdG8ga2VlcCBzdXBw b3J0IGZvciB0aGlzIGNvbXBhdGlibGUgc3RyaW5nIGZvciBiYWNrd2FyZCAKY29tcGF0aWJpbGl0 eS4KCj4gKwl7Cj4gKwkJLmNvbXBhdGlibGUgPSAiZHVtYi12Z2EtZGFjIiwKPiArCQkuZGF0YSA9 ICZkZWZhdWx0X2RhY192YXJpYW50LAo+ICsJfSwKPiArCXsKPiArCQkuY29tcGF0aWJsZSA9ICJh ZGksYWR2NzEyMyIsCj4gKwkJLmRhdGEgPSAmZGVmYXVsdF9kYWNfdmFyaWFudCwKPiArCX0sCj4g Kwl7Cj4gKwkJLmNvbXBhdGlibGUgPSAidGksdGhzODEzeCIsCj4gKwkJLmRhdGEgPSAmdGlfdGhz X2RhY192YXJpYW50LAo+ICsJfSwKPiAgCXt9LAo+ICB9Owo+ICBNT0RVTEVfREVWSUNFX1RBQkxF KG9mLCBkdW1iX3ZnYV9tYXRjaCk7CgotLSAKUmVnYXJkcywKCkxhdXJlbnQgUGluY2hhcnQKCl9f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBt YWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3Rz LmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=