From mboxrd@z Thu Jan 1 00:00:00 1970 From: moinejf@free.fr (Jean-Francois Moine) Date: Sat, 18 May 2013 19:45:02 +0200 Subject: [RFC 3/4] DRM: add OF support for Dove DRM driver In-Reply-To: <1368897139-25485-4-git-send-email-sebastian.hesselbarth@gmail.com> References: <20130516192510.GV18614@n2100.arm.linux.org.uk> <1368897139-25485-1-git-send-email-sebastian.hesselbarth@gmail.com> <1368897139-25485-4-git-send-email-sebastian.hesselbarth@gmail.com> Message-ID: <20130518194502.102caa9e@armhf> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Sat, 18 May 2013 19:12:18 +0200 Sebastian Hesselbarth wrote: > This adds OF support for the Dove DRM driver recently posted as RFC by > Russell King. > > Signed-off-by: Sebastian Hesselbarth > --- > Cc: Russell King > Cc: linux-arm-kernel at lists.infradead.org > Cc: dri-devel at lists.freedesktop.org > Cc: Jason Cooper > Cc: Jean-Francois Moine > --- > drivers/gpu/drm/dove/Kconfig | 4 ++ > drivers/gpu/drm/dove/Makefile | 1 + > drivers/gpu/drm/dove/dove_card.c | 110 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 115 insertions(+) > create mode 100644 drivers/gpu/drm/dove/dove_card.c > > diff --git a/drivers/gpu/drm/dove/Kconfig b/drivers/gpu/drm/dove/Kconfig > index 718d3c5..a943ea5 100644 > --- a/drivers/gpu/drm/dove/Kconfig > +++ b/drivers/gpu/drm/dove/Kconfig > @@ -28,4 +28,8 @@ config DRM_DOVE_TDA1998X > config DRM_DOVE_CURSOR > bool "Enable Dove DRM hardware cursor support" > > +config DRM_DOVE_OF > + bool "Enable Dove DRM OF video card" > + depends on OF > + > endif > diff --git a/drivers/gpu/drm/dove/Makefile b/drivers/gpu/drm/dove/Makefile > index 65c701e..f0b6eed 100644 > --- a/drivers/gpu/drm/dove/Makefile > +++ b/drivers/gpu/drm/dove/Makefile > @@ -5,5 +5,6 @@ dove-y := dove_crtc.o dove_drv.o dove_fb.o dove_fbdev.o \ > dove-$(CONFIG_DEBUG_FS) += dove_debugfs.o > > dove-$(CONFIG_DRM_DOVE_TDA1998X) += dove_tda19988.o > +dove-$(CONFIG_DRM_DOVE_OF) += dove_card.o > > obj-$(CONFIG_DRM_DOVE) := dove.o > diff --git a/drivers/gpu/drm/dove/dove_card.c b/drivers/gpu/drm/dove/dove_card.c > new file mode 100644 > index 0000000..e4bcb5b > --- /dev/null > +++ b/drivers/gpu/drm/dove/dove_card.c > @@ -0,0 +1,110 @@ > +/* > + * Copyright (C) 2013 > + * Sebastian Hesselbarth > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define DOVE_LCD0_BASE 0x20000 > +#define DOVE_LCD1_BASE 0x10000 > + > +static struct resource dove_drm_resources[5]; > +static struct platform_device dove_drm_platform_device = { > + .name = "dove-drm", > + .id = 0, > + .dev = { .coherent_dma_mask = ~0, }, > + .resource = dove_drm_resources, > +}; > + > +static int dove_card_probe(struct platform_device *pdev) > +{ > + struct device_node *np = pdev->dev.of_node; > + struct device_node *lcdnp; > + struct resource *res = dove_drm_resources; > + int ret, n = 0, crtcs = 0; > + > + /* get video memory resource */ > + if (of_address_to_resource(np, 0, &res[n++])) { > + dev_err(&pdev->dev, "invalid or missing video memory\n"); > + return -EINVAL; > + } > + > + /* get reg and irq resource from each enabled lcdc */ > + for_each_compatible_node(lcdnp, NULL, "marvell,dove-lcd") { > + struct clk_lookup *cl; > + struct clk *clk; > + int lcd; > + > + if (!of_device_is_available(lcdnp)) > + continue; > + > + ret = of_address_to_resource(lcdnp, 0, &res[n]); > + if (ret) > + return ret; > + lcd = ((res[n].start & 0xfffff) == DOVE_LCD1_BASE); > + n++; > + > + ret = of_irq_to_resource(lcdnp, 0, &res[n]); > + if (ret < 0) > + return ret; > + n++; > + > + crtcs++; > + > + clk = clk_get(&pdev->dev, NULL); > + if (IS_ERR(clk)) { > + ret = PTR_ERR(clk); > + if (ret == -ENOENT) > + return -EPROBE_DEFER; > + return ret; > + } > + > + /* add clock alias for dovefb.0 */ > + cl = clkdev_alloc(clk, "extclk", "dovefb.0"); > + if (cl) > + clkdev_add(cl); > + clk_put(clk); > + } > + > + if (!crtcs) > + return -ENODEV; > + > + dove_drm_platform_device.num_resources = n; > + ret = platform_device_register(&dove_drm_platform_device); > + if (ret) { > + dev_err(&pdev->dev, "unable to register drm device\n"); > + return ret; > + } > + > + return 0; > +} > + > +static const struct of_device_id dove_card_of_ids[] = { > + { .compatible = "marvell,dove-video-card", }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, dove_card_of_ids); > + > +static struct platform_driver dove_card_driver = { > + .probe = dove_card_probe, > + .driver = { > + .owner = THIS_MODULE, > + .name = "dove-drm-card", > + .of_match_table = of_match_ptr(dove_card_of_ids), > + }, > +}; > +module_platform_driver(dove_card_driver); > + > +MODULE_AUTHOR("Sebastian Hesselbarth "); > +MODULE_DESCRIPTION("Dove DRM Graphics Card"); > +MODULE_LICENSE("GPL"); It seems we are moving backwards: - what about the display controller? - how do you clone the lcd 0 output to the port B? - what occurs when the si5351 and the tda998x are modules? My driver had the same layout as Russell's when I proposed it to you and when you insisted to handle the 2 LCDs and the 2 ports as one card. I spent 2 months to have a nice design and you put it to garbage! I am not happy... -- Ken ar c'henta? | ** Breizh ha Linux atav! ** Jef | http://moinejf.free.fr/ From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jean-Francois Moine Subject: Re: [RFC 3/4] DRM: add OF support for Dove DRM driver Date: Sat, 18 May 2013 19:45:02 +0200 Message-ID: <20130518194502.102caa9e@armhf> References: <20130516192510.GV18614@n2100.arm.linux.org.uk> <1368897139-25485-1-git-send-email-sebastian.hesselbarth@gmail.com> <1368897139-25485-4-git-send-email-sebastian.hesselbarth@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1368897139-25485-4-git-send-email-sebastian.hesselbarth@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: Sebastian Hesselbarth Cc: Russell King , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, Jason Cooper List-Id: dri-devel@lists.freedesktop.org T24gU2F0LCAxOCBNYXkgMjAxMyAxOToxMjoxOCArMDIwMApTZWJhc3RpYW4gSGVzc2VsYmFydGgg PHNlYmFzdGlhbi5oZXNzZWxiYXJ0aEBnbWFpbC5jb20+IHdyb3RlOgoKPiBUaGlzIGFkZHMgT0Yg c3VwcG9ydCBmb3IgdGhlIERvdmUgRFJNIGRyaXZlciByZWNlbnRseSBwb3N0ZWQgYXMgUkZDIGJ5 Cj4gUnVzc2VsbCBLaW5nLgo+IAo+IFNpZ25lZC1vZmYtYnk6IFNlYmFzdGlhbiBIZXNzZWxiYXJ0 aCA8c2ViYXN0aWFuLmhlc3NlbGJhcnRoQGdtYWlsLmNvbT4KPiAtLS0KPiBDYzogUnVzc2VsbCBL aW5nIDxsaW51eEBhcm0ubGludXgub3JnLnVrPgo+IENjOiBsaW51eC1hcm0ta2VybmVsQGxpc3Rz LmluZnJhZGVhZC5vcmcKPiBDYzogZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwo+IENj OiBKYXNvbiBDb29wZXIgPGphc29uQGxha2VkYWVtb24ubmV0Pgo+IENjOiBKZWFuLUZyYW5jb2lz IE1vaW5lIDxtb2luZWpmQGZyZWUuZnI+Cj4gLS0tCj4gIGRyaXZlcnMvZ3B1L2RybS9kb3ZlL0tj b25maWcgICAgIHwgICAgNCArKwo+ICBkcml2ZXJzL2dwdS9kcm0vZG92ZS9NYWtlZmlsZSAgICB8 ICAgIDEgKwo+ICBkcml2ZXJzL2dwdS9kcm0vZG92ZS9kb3ZlX2NhcmQuYyB8ICAxMTAgKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPiAgMyBmaWxlcyBjaGFuZ2VkLCAxMTUg aW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL2RvdmUv ZG92ZV9jYXJkLmMKPiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2RvdmUvS2NvbmZp ZyBiL2RyaXZlcnMvZ3B1L2RybS9kb3ZlL0tjb25maWcKPiBpbmRleCA3MThkM2M1Li5hOTQzZWE1 IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9kb3ZlL0tjb25maWcKPiArKysgYi9kcml2 ZXJzL2dwdS9kcm0vZG92ZS9LY29uZmlnCj4gQEAgLTI4LDQgKzI4LDggQEAgY29uZmlnIERSTV9E T1ZFX1REQTE5OThYCj4gIGNvbmZpZyBEUk1fRE9WRV9DVVJTT1IKPiAgCWJvb2wgIkVuYWJsZSBE b3ZlIERSTSBoYXJkd2FyZSBjdXJzb3Igc3VwcG9ydCIKPiAgCj4gK2NvbmZpZyBEUk1fRE9WRV9P Rgo+ICsJYm9vbCAiRW5hYmxlIERvdmUgRFJNIE9GIHZpZGVvIGNhcmQiCj4gKwlkZXBlbmRzIG9u IE9GCj4gKwo+ICBlbmRpZgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vZG92ZS9NYWtl ZmlsZSBiL2RyaXZlcnMvZ3B1L2RybS9kb3ZlL01ha2VmaWxlCj4gaW5kZXggNjVjNzAxZS4uZjBi NmVlZCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vZG92ZS9NYWtlZmlsZQo+ICsrKyBi L2RyaXZlcnMvZ3B1L2RybS9kb3ZlL01ha2VmaWxlCj4gQEAgLTUsNSArNSw2IEBAIGRvdmUteQkJ CTo9IGRvdmVfY3J0Yy5vIGRvdmVfZHJ2Lm8gZG92ZV9mYi5vIGRvdmVfZmJkZXYubyBcCj4gIGRv dmUtJChDT05GSUdfREVCVUdfRlMpICs9IGRvdmVfZGVidWdmcy5vCj4gIAo+ICBkb3ZlLSQoQ09O RklHX0RSTV9ET1ZFX1REQTE5OThYKSArPSBkb3ZlX3RkYTE5OTg4Lm8KPiArZG92ZS0kKENPTkZJ R19EUk1fRE9WRV9PRikgKz0gZG92ZV9jYXJkLm8KPiAgCj4gIG9iai0kKENPTkZJR19EUk1fRE9W RSkgOj0gZG92ZS5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9kb3ZlL2RvdmVfY2Fy ZC5jIGIvZHJpdmVycy9ncHUvZHJtL2RvdmUvZG92ZV9jYXJkLmMKPiBuZXcgZmlsZSBtb2RlIDEw MDY0NAo+IGluZGV4IDAwMDAwMDAuLmU0YmNiNWIKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJp dmVycy9ncHUvZHJtL2RvdmUvZG92ZV9jYXJkLmMKPiBAQCAtMCwwICsxLDExMCBAQAo+ICsvKgo+ ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTMKPiArICogICBTZWJhc3RpYW4gSGVzc2VsYmFydGggPHNl YmFzdGlhbi5oZXNzZWxiYXJ0aEBnbWFpbC5jb20+Cj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBp cyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cj4g KyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2Ug dmVyc2lvbiAyIGFzCj4gKyAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0 aW9uLgo+ICsgKi8KPiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgo+ICsjaW5jbHVkZSA8bGludXgv Y2xrZGV2Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L29mLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZl9hZGRyZXNzLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9vZl9pcnEuaD4KPiArI2luY2x1ZGUgPGxpbnV4L29mX3BsYXRmb3JtLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KPiArCj4gKyNkZWZpbmUgRE9WRV9MQ0QwX0JBU0UJ MHgyMDAwMAo+ICsjZGVmaW5lIERPVkVfTENEMV9CQVNFCTB4MTAwMDAKPiArCj4gK3N0YXRpYyBz dHJ1Y3QgcmVzb3VyY2UgZG92ZV9kcm1fcmVzb3VyY2VzWzVdOwo+ICtzdGF0aWMgc3RydWN0IHBs YXRmb3JtX2RldmljZSBkb3ZlX2RybV9wbGF0Zm9ybV9kZXZpY2UgPSB7Cj4gKwkubmFtZSA9ICJk b3ZlLWRybSIsCj4gKwkuaWQgPSAwLAo+ICsJLmRldiA9IHsgLmNvaGVyZW50X2RtYV9tYXNrID0g fjAsIH0sCj4gKwkucmVzb3VyY2UgPSBkb3ZlX2RybV9yZXNvdXJjZXMsCj4gK307Cj4gKwo+ICtz dGF0aWMgaW50IGRvdmVfY2FyZF9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ ICt7Cj4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wID0gcGRldi0+ZGV2Lm9mX25vZGU7Cj4gKwlz dHJ1Y3QgZGV2aWNlX25vZGUgKmxjZG5wOwo+ICsJc3RydWN0IHJlc291cmNlICpyZXMgPSBkb3Zl X2RybV9yZXNvdXJjZXM7Cj4gKwlpbnQgcmV0LCBuID0gMCwgY3J0Y3MgPSAwOwo+ICsKPiArCS8q IGdldCB2aWRlbyBtZW1vcnkgcmVzb3VyY2UgKi8KPiArCWlmIChvZl9hZGRyZXNzX3RvX3Jlc291 cmNlKG5wLCAwLCAmcmVzW24rK10pKSB7Cj4gKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiaW52YWxp ZCBvciBtaXNzaW5nIHZpZGVvIG1lbW9yeVxuIik7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9 Cj4gKwo+ICsJLyogZ2V0IHJlZyBhbmQgaXJxIHJlc291cmNlIGZyb20gZWFjaCBlbmFibGVkIGxj ZGMgKi8KPiArCWZvcl9lYWNoX2NvbXBhdGlibGVfbm9kZShsY2RucCwgTlVMTCwgIm1hcnZlbGws ZG92ZS1sY2QiKSB7Cj4gKwkJc3RydWN0IGNsa19sb29rdXAgKmNsOwo+ICsJCXN0cnVjdCBjbGsg KmNsazsKPiArCQlpbnQgbGNkOwo+ICsKPiArCQlpZiAoIW9mX2RldmljZV9pc19hdmFpbGFibGUo bGNkbnApKQo+ICsJCQljb250aW51ZTsKPiArCj4gKwkJcmV0ID0gb2ZfYWRkcmVzc190b19yZXNv dXJjZShsY2RucCwgMCwgJnJlc1tuXSk7Cj4gKwkJaWYgKHJldCkKPiArCQkJcmV0dXJuIHJldDsK PiArCQlsY2QgPSAoKHJlc1tuXS5zdGFydCAmIDB4ZmZmZmYpID09IERPVkVfTENEMV9CQVNFKTsK PiArCQluKys7Cj4gKwo+ICsJCXJldCA9IG9mX2lycV90b19yZXNvdXJjZShsY2RucCwgMCwgJnJl c1tuXSk7Cj4gKwkJaWYgKHJldCA8IDApCj4gKwkJCXJldHVybiByZXQ7Cj4gKwkJbisrOwo+ICsK PiArCQljcnRjcysrOwo+ICsKPiArCQljbGsgPSBjbGtfZ2V0KCZwZGV2LT5kZXYsIE5VTEwpOwo+ ICsJCWlmIChJU19FUlIoY2xrKSkgewo+ICsJCQlyZXQgPSBQVFJfRVJSKGNsayk7Cj4gKwkJCWlm IChyZXQgPT0gLUVOT0VOVCkKPiArCQkJCXJldHVybiAtRVBST0JFX0RFRkVSOwo+ICsJCQlyZXR1 cm4gcmV0Owo+ICsJCX0KPiArCj4gKwkJLyogYWRkIGNsb2NrIGFsaWFzIGZvciBkb3ZlZmIuMCAq Lwo+ICsJCWNsID0gY2xrZGV2X2FsbG9jKGNsaywgImV4dGNsayIsICJkb3ZlZmIuMCIpOwo+ICsJ CWlmIChjbCkKPiArCQkJY2xrZGV2X2FkZChjbCk7Cj4gKwkJY2xrX3B1dChjbGspOwo+ICsJfQo+ ICsKPiArCWlmICghY3J0Y3MpCj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gKwo+ICsJZG92ZV9kcm1f cGxhdGZvcm1fZGV2aWNlLm51bV9yZXNvdXJjZXMgPSBuOwo+ICsJcmV0ID0gcGxhdGZvcm1fZGV2 aWNlX3JlZ2lzdGVyKCZkb3ZlX2RybV9wbGF0Zm9ybV9kZXZpY2UpOwo+ICsJaWYgKHJldCkgewo+ ICsJCWRldl9lcnIoJnBkZXYtPmRldiwgInVuYWJsZSB0byByZWdpc3RlciBkcm0gZGV2aWNlXG4i KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtz dGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBkb3ZlX2NhcmRfb2ZfaWRzW10gPSB7Cj4g Kwl7IC5jb21wYXRpYmxlID0gIm1hcnZlbGwsZG92ZS12aWRlby1jYXJkIiwgfSwKPiArCXsgfQo+ ICt9Owo+ICtNT0RVTEVfREVWSUNFX1RBQkxFKG9mLCBkb3ZlX2NhcmRfb2ZfaWRzKTsKPiArCj4g K3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIGRvdmVfY2FyZF9kcml2ZXIgPSB7Cj4gKwku cHJvYmUJPSBkb3ZlX2NhcmRfcHJvYmUsCj4gKwkuZHJpdmVyCT0gewo+ICsJCS5vd25lcgk9IFRI SVNfTU9EVUxFLAo+ICsJCS5uYW1lCT0gImRvdmUtZHJtLWNhcmQiLAo+ICsJCS5vZl9tYXRjaF90 YWJsZSA9IG9mX21hdGNoX3B0cihkb3ZlX2NhcmRfb2ZfaWRzKSwKPiArCX0sCj4gK307Cj4gK21v ZHVsZV9wbGF0Zm9ybV9kcml2ZXIoZG92ZV9jYXJkX2RyaXZlcik7Cj4gKwo+ICtNT0RVTEVfQVVU SE9SKCJTZWJhc3RpYW4gSGVzc2VsYmFydGggPHNlYmFzdGlhbi5oZXNzZWxiYXJ0aEBnbWFpbC5j b20+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiRG92ZSBEUk0gR3JhcGhpY3MgQ2FyZCIpOwo+ ICtNT0RVTEVfTElDRU5TRSgiR1BMIik7CgpJdCBzZWVtcyB3ZSBhcmUgbW92aW5nIGJhY2t3YXJk czoKLSB3aGF0IGFib3V0IHRoZSBkaXNwbGF5IGNvbnRyb2xsZXI/Ci0gaG93IGRvIHlvdSBjbG9u ZSB0aGUgbGNkIDAgb3V0cHV0IHRvIHRoZSBwb3J0IEI/Ci0gd2hhdCBvY2N1cnMgd2hlbiB0aGUg c2k1MzUxIGFuZCB0aGUgdGRhOTk4eCBhcmUgbW9kdWxlcz8KCk15IGRyaXZlciBoYWQgdGhlIHNh bWUgbGF5b3V0IGFzIFJ1c3NlbGwncyB3aGVuIEkgcHJvcG9zZWQgaXQgdG8geW91CmFuZCB3aGVu IHlvdSBpbnNpc3RlZCB0byBoYW5kbGUgdGhlIDIgTENEcyBhbmQgdGhlIDIgcG9ydHMgYXMgb25l IGNhcmQuCkkgc3BlbnQgMiBtb250aHMgdG8gaGF2ZSBhIG5pY2UgZGVzaWduIGFuZCB5b3UgcHV0 IGl0IHRvIGdhcmJhZ2UhCkkgYW0gbm90IGhhcHB5Li4uCgotLSAKS2VuIGFyIGMnaGVudGHDsQl8 CSAgICAgICoqIEJyZWl6aCBoYSBMaW51eCBhdGF2ISAqKgpKZWYJCXwJCWh0dHA6Ly9tb2luZWpm LmZyZWUuZnIvCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmlu ZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9s aW51eC1hcm0ta2VybmVsCg==