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 X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,MIME_HEADER_CTYPE_ONLY,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,T_TVD_MIME_NO_HEADERS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 693CAC433E2 for ; Fri, 11 Sep 2020 17:55:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 271A6221ED for ; Fri, 11 Sep 2020 17:55:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="NORaEquQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726073AbgIKRzE (ORCPT ); Fri, 11 Sep 2020 13:55:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725836AbgIKRwq (ORCPT ); Fri, 11 Sep 2020 13:52:46 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0905DC061786 for ; Fri, 11 Sep 2020 10:52:46 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id 5so7171999pgl.4 for ; Fri, 11 Sep 2020 10:52:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=46jFD8dIJ8oLWscp9uOqVO6G8a1HMxwH5FHeZ7ERP1o=; b=NORaEquQ/+mNAkWbXX9U43vin1MtVZTP2qH9te7QzInrBRR7AJU9Lz2YILclx9CqR+ elWgEdHf99VJ5005qqHTqW/XyUV4cB0xXHt/638m1EEKlXxZ9kJ8vGJy3TRMh+OtJCEd RmQWbYnQsX5Oxa4bJOJBQHhr7XPJbMBCNub28= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=46jFD8dIJ8oLWscp9uOqVO6G8a1HMxwH5FHeZ7ERP1o=; b=rQf4eUD0NFbqzPLaAnfhHPh8Z1JRgw5n3Otlt3g2RbcysReUsGZ3bcaZklWzBvKedB Q5d2Ns59OqMLPaCG1v3JPxmxW7iDKv44fmaorERAvVdmhQFt6wkvofQA6EaniLmb7IXj a3ljQ2/rQQp7BaplWdy5YVXGaLa0qTCrRSLcqWa4zfla6elPDXn9jn/tK3TA8eno1tVl XBVRI62rPa1JZ4Kr9FxiygScYiZrsYIw4664ZigM9y3DiDhO3CiZcUzMTnUSDY7QOIYN 3mWUAnb1wPbY6AilRIPhSGQe1EyoGVjLFW5KCOb2hih4ZzljQoO3CavYro0Ox4qqoCLC 0g8g== X-Gm-Message-State: AOAM530fjeMjF5+teLWpHRARcxbZDBFOAyk7OtoRngFkvBU5YDeIPv8D ft/9akla0b4sZNjzphJNgh4kMQ== X-Google-Smtp-Source: ABdhPJyaWEHsZb6i9SNd1/wfkIihgOZBSC8hoPo3WzRlMi7E2cdQVs7wtkBNVx/ei0n8dYsOyjuVeQ== X-Received: by 2002:a62:19c1:0:b029:13c:1611:6529 with SMTP id 184-20020a6219c10000b029013c16116529mr3127501pfz.9.1599846765315; Fri, 11 Sep 2020 10:52:45 -0700 (PDT) Received: from stbsrv-and-01.and.broadcom.net ([192.19.231.250]) by smtp.gmail.com with ESMTPSA id d77sm2871963pfd.121.2020.09.11.10.52.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2020 10:52:44 -0700 (PDT) From: Jim Quinlan To: linux-pci@vger.kernel.org, Nicolas Saenz Julienne , Christoph Hellwig , Robin Murphy , bcm-kernel-feedback-list@broadcom.com, james.quinlan@broadcom.com Cc: Jim Quinlan , Lorenzo Pieralisi , Rob Herring , Bjorn Helgaas , Florian Fainelli , linux-rpi-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v12 03/10] PCI: brcmstb: Add bcm7278 register info Date: Fri, 11 Sep 2020 13:52:23 -0400 Message-Id: <20200911175232.19016-4-james.quinlan@broadcom.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200911175232.19016-1-james.quinlan@broadcom.com> References: <20200911175232.19016-1-james.quinlan@broadcom.com> Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="0000000000002c23fb05af0d5af2" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --0000000000002c23fb05af0d5af2 From: Jim Quinlan Add in compatibility strings and code for three Broadcom STB chips. Some of the register locations, shifts, and masks are different for certain chips, requiring the use of different constants based on of_id. We would like to add the following at this time to the match list but we need to wait until the end of this patchset so that everything works. { .compatible = "brcm,bcm7211-pcie", .data = &generic_cfg }, { .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg }, { .compatible = "brcm,bcm7216-pcie", .data = &bcm7278_cfg }, { .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg }, Signed-off-by: Jim Quinlan Acked-by: Florian Fainelli Acked-by: Rob Herring --- drivers/pci/controller/pcie-brcmstb.c | 105 +++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 12 deletions(-) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 85fa7d54f11f..c2b3d2946a36 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -122,9 +122,8 @@ #define PCIE_EXT_SLOT_SHIFT 15 #define PCIE_EXT_FUNC_SHIFT 12 -#define PCIE_RGR1_SW_INIT_1 0x9210 #define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1 -#define PCIE_RGR1_SW_INIT_1_INIT_MASK 0x2 +#define PCIE_RGR1_SW_INIT_1_PERST_SHIFT 0x0 /* PCIe parameters */ #define BRCM_NUM_PCIE_OUT_WINS 0x4 @@ -154,6 +153,73 @@ #define SSC_STATUS_SSC_MASK 0x400 #define SSC_STATUS_PLL_LOCK_MASK 0x800 +#define IDX_ADDR(pcie) (pcie->reg_offsets[EXT_CFG_INDEX]) +#define DATA_ADDR(pcie) (pcie->reg_offsets[EXT_CFG_DATA]) +#define PCIE_RGR1_SW_INIT_1(pcie) (pcie->reg_offsets[RGR1_SW_INIT_1]) + +enum { + RGR1_SW_INIT_1, + EXT_CFG_INDEX, + EXT_CFG_DATA, +}; + +enum { + RGR1_SW_INIT_1_INIT_MASK, + RGR1_SW_INIT_1_INIT_SHIFT, +}; + +enum pcie_type { + GENERIC, + BCM7278, + BCM2711, +}; + +struct pcie_cfg_data { + const int *reg_field_info; + const int *offsets; + const enum pcie_type type; +}; + +static const int pcie_reg_field_info[] = { + [RGR1_SW_INIT_1_INIT_MASK] = 0x2, + [RGR1_SW_INIT_1_INIT_SHIFT] = 0x1, +}; + +static const int pcie_reg_field_info_bcm7278[] = { + [RGR1_SW_INIT_1_INIT_MASK] = 0x1, + [RGR1_SW_INIT_1_INIT_SHIFT] = 0x0, +}; + +static const int pcie_offsets[] = { + [RGR1_SW_INIT_1] = 0x9210, + [EXT_CFG_INDEX] = 0x9000, + [EXT_CFG_DATA] = 0x9004, +}; + +static const struct pcie_cfg_data generic_cfg = { + .reg_field_info = pcie_reg_field_info, + .offsets = pcie_offsets, + .type = GENERIC, +}; + +static const int pcie_offset_bcm7278[] = { + [RGR1_SW_INIT_1] = 0xc010, + [EXT_CFG_INDEX] = 0x9000, + [EXT_CFG_DATA] = 0x9004, +}; + +static const struct pcie_cfg_data bcm7278_cfg = { + .reg_field_info = pcie_reg_field_info_bcm7278, + .offsets = pcie_offset_bcm7278, + .type = BCM7278, +}; + +static const struct pcie_cfg_data bcm2711_cfg = { + .reg_field_info = pcie_reg_field_info, + .offsets = pcie_offsets, + .type = BCM2711, +}; + struct brcm_msi { struct device *dev; void __iomem *base; @@ -177,6 +243,9 @@ struct brcm_pcie { int gen; u64 msi_target_addr; struct brcm_msi *msi; + const int *reg_offsets; + const int *reg_field_info; + enum pcie_type type; }; /* @@ -603,20 +672,21 @@ static struct pci_ops brcm_pcie_ops = { static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, u32 val) { - u32 tmp; + u32 tmp, mask = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_MASK]; + u32 shift = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_SHIFT]; - tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1); - u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_INIT_MASK); - writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1); + tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); + tmp = (tmp & ~mask) | ((val << shift) & mask); + writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); } static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, u32 val) { u32 tmp; - tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1); + tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_PERST_MASK); - writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1); + writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); } static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie, @@ -927,11 +997,17 @@ static int brcm_pcie_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id brcm_pcie_match[] = { + { .compatible = "brcm,bcm2711-pcie", .data = &bcm2711_cfg }, + {}, +}; + static int brcm_pcie_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node, *msi_np; struct pci_host_bridge *bridge; struct device_node *fw_np; + const struct pcie_cfg_data *data; struct brcm_pcie *pcie; int ret; @@ -953,9 +1029,18 @@ static int brcm_pcie_probe(struct platform_device *pdev) if (!bridge) return -ENOMEM; + data = of_device_get_match_data(&pdev->dev); + if (!data) { + pr_err("failed to look up compatible string\n"); + return -EINVAL; + } + pcie = pci_host_bridge_priv(bridge); pcie->dev = &pdev->dev; pcie->np = np; + pcie->reg_offsets = data->offsets; + pcie->reg_field_info = data->reg_field_info; + pcie->type = data->type; pcie->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pcie->base)) @@ -1000,10 +1085,6 @@ static int brcm_pcie_probe(struct platform_device *pdev) return ret; } -static const struct of_device_id brcm_pcie_match[] = { - { .compatible = "brcm,bcm2711-pcie" }, - {}, -}; MODULE_DEVICE_TABLE(of, brcm_pcie_match); static struct platform_driver brcm_pcie_driver = { -- 2.17.1 --0000000000002c23fb05af0d5af2 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIIQQwYJKoZIhvcNAQcCoIIQNDCCEDACAQExDzANBglghkgBZQMEAgEFADALBgkqhkiG9w0BBwGg gg2YMIIE6DCCA9CgAwIBAgIOSBtqCRO9gCTKXSLwFPMwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UE CxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMT Ckdsb2JhbFNpZ24wHhcNMTYwNjE1MDAwMDAwWhcNMjQwNjE1MDAwMDAwWjBdMQswCQYDVQQGEwJC RTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEzMDEGA1UEAxMqR2xvYmFsU2lnbiBQZXJzb25h bFNpZ24gMiBDQSAtIFNIQTI1NiAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA tpZok2X9LAHsYqMNVL+Ly6RDkaKar7GD8rVtb9nw6tzPFnvXGeOEA4X5xh9wjx9sScVpGR5wkTg1 fgJIXTlrGESmaqXIdPRd9YQ+Yx9xRIIIPu3Jp/bpbiZBKYDJSbr/2Xago7sb9nnfSyjTSnucUcIP ZVChn6hKneVGBI2DT9yyyD3PmCEJmEzA8Y96qT83JmVH2GaPSSbCw0C+Zj1s/zqtKUbwE5zh8uuZ p4vC019QbaIOb8cGlzgvTqGORwK0gwDYpOO6QQdg5d03WvIHwTunnJdoLrfvqUg2vOlpqJmqR+nH 9lHS+bEstsVJtZieU1Pa+3LzfA/4cT7XA/pnwwIDAQABo4IBtTCCAbEwDgYDVR0PAQH/BAQDAgEG MGoGA1UdJQRjMGEGCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwkGCisGAQQBgjcUAgIGCisG AQQBgjcKAwQGCSsGAQQBgjcVBgYKKwYBBAGCNwoDDAYIKwYBBQUHAwcGCCsGAQUFBwMRMBIGA1Ud EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFGlygmIxZ5VEhXeRgMQENkmdewthMB8GA1UdIwQYMBaA FI/wS3+oLkUkrk1Q+mOai97i3Ru8MD4GCCsGAQUFBwEBBDIwMDAuBggrBgEFBQcwAYYiaHR0cDov L29jc3AyLmdsb2JhbHNpZ24uY29tL3Jvb3RyMzA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3Js Lmdsb2JhbHNpZ24uY29tL3Jvb3QtcjMuY3JsMGcGA1UdIARgMF4wCwYJKwYBBAGgMgEoMAwGCisG AQQBoDIBKAowQQYJKwYBBAGgMgFfMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNp Z24uY29tL3JlcG9zaXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQConc0yzHxn4gtQ16VccKNm4iXv 6rS2UzBuhxI3XDPiwihW45O9RZXzWNgVcUzz5IKJFL7+pcxHvesGVII+5r++9eqI9XnEKCILjHr2 DgvjKq5Jmg6bwifybLYbVUoBthnhaFB0WLwSRRhPrt5eGxMw51UmNICi/hSKBKsHhGFSEaJQALZy 4HL0EWduE6ILYAjX6BSXRDtHFeUPddb46f5Hf5rzITGLsn9BIpoOVrgS878O4JnfUWQi29yBfn75 HajifFvPC+uqn+rcVnvrpLgsLOYG/64kWX/FRH8+mhVe+mcSX3xsUpcxK9q9vLTVtroU/yJUmEC4 OcH5dQsbHBqjMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNV BAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQL ExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMK R2xvYmFsU2lnbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aE yiie/QV2EcWtiHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5 uzsTgHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bL yCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg 6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkW qQPabumDk3F2xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w HQYDVR0OBBYEFI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+ yAzv95ZURUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5 RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBov Hd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX42 68NXSb7hLi18YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o 2HLO02JQZR7rkpeDMdmztcpHWD9fMIIFRTCCBC2gAwIBAgIME79sZrUeCjpiuELzMA0GCSqGSIb3 DQEBCwUAMF0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTMwMQYDVQQD EypHbG9iYWxTaWduIFBlcnNvbmFsU2lnbiAyIENBIC0gU0hBMjU2IC0gRzMwHhcNMjAwOTA0MDcw ODQ0WhcNMjIwOTA1MDcwODQ0WjCBjjELMAkGA1UEBhMCSU4xEjAQBgNVBAgTCUthcm5hdGFrYTES MBAGA1UEBxMJQmFuZ2Fsb3JlMRYwFAYDVQQKEw1Ccm9hZGNvbSBJbmMuMRQwEgYDVQQDEwtKaW0g UXVpbmxhbjEpMCcGCSqGSIb3DQEJARYaamFtZXMucXVpbmxhbkBicm9hZGNvbS5jb20wggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDqsBkKCQn3+AT8d+247+l35R4b3HcQmAIBLNwR78Pv pMo/m+/bgJGpfN9+2p6a/M0l8nzvM+kaKcDdXKfYrnSGE5t+AFFb6dQD1UbJAX1IpZLyjTC215h2 49CKrg1K58cBpU95z5THwRvY/lDS1AyNJ8LkrKF20wMGQzam3LVfmrYHEUPSsMOVw7rRMSbVSGO9 +I2BkxB5dBmbnwpUPXY5+Mx6BEac1mEWA5+7anZeAAxsyvrER6cbU8MwwlrORp5lkeqDQKW3FIZB mOxPm7sNHsn0TVdPryi9+T2d8fVC/kUmuEdTYP/Hdu4W4b4T9BcW57fInYrmaJ+uotS6X59rAgMB AAGjggHRMIIBzTAOBgNVHQ8BAf8EBAMCBaAwgZ4GCCsGAQUFBwEBBIGRMIGOME0GCCsGAQUFBzAC hkFodHRwOi8vc2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9nc3BlcnNvbmFsc2lnbjJzaGEy ZzNvY3NwLmNydDA9BggrBgEFBQcwAYYxaHR0cDovL29jc3AyLmdsb2JhbHNpZ24uY29tL2dzcGVy c29uYWxzaWduMnNoYTJnMzBNBgNVHSAERjBEMEIGCisGAQQBoDIBKAowNDAyBggrBgEFBQcCARYm aHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCQYDVR0TBAIwADBEBgNVHR8E PTA7MDmgN6A1hjNodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2dzcGVyc29uYWxzaWduMnNoYTJn My5jcmwwJQYDVR0RBB4wHIEaamFtZXMucXVpbmxhbkBicm9hZGNvbS5jb20wEwYDVR0lBAwwCgYI KwYBBQUHAwQwHwYDVR0jBBgwFoAUaXKCYjFnlUSFd5GAxAQ2SZ17C2EwHQYDVR0OBBYEFNYm4GDl 4WOt3laB3gNKFfYyaM8bMA0GCSqGSIb3DQEBCwUAA4IBAQBD+XYEgpG/OqeRgXAgDF8sa+lQ/00T wCP/3nBzwZPblTyThtDE/iaL/YZ5rdwqXwdCnSFh9cMhd/bnA+Eqw89clgTixvz9MdL9Vuo8LACI VpHO+sxZ2Cu3bO5lpK+UVCyr21y1zumOICsOuu4MJA5mtkpzBXQiA7b/ogjGxG+5iNjt9FAMX4JP V6GuAMmRknrzeTlxPy40UhUcRKk6Nm8mxl3Jh4KB68z7NFVpIx8G5w5I7S5ar1mLGNRjtFZ0RE4O lcCwKVGUXRaZMgQGrIhxGVelVgrcBh2vjpndlv733VI2VKE/TvV5MxMGU18RnogYSm66AEFA/Zb+ 5ztz1AtIMYICbzCCAmsCAQEwbTBdMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBu di1zYTEzMDEGA1UEAxMqR2xvYmFsU2lnbiBQZXJzb25hbFNpZ24gMiBDQSAtIFNIQTI1NiAtIEcz AgwTv2xmtR4KOmK4QvMwDQYJYIZIAWUDBAIBBQCggdQwLwYJKoZIhvcNAQkEMSIEIGSZC7W09XzM 1+4tTfo7n7Ed2R6+7UVgIJez/q2ke3aMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZI hvcNAQkFMQ8XDTIwMDkxMTE3NTI0NVowaQYJKoZIhvcNAQkPMVwwWjALBglghkgBZQMEASowCwYJ YIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzALBgkqhkiG9w0BAQowCwYJKoZIhvcN AQEHMAsGCWCGSAFlAwQCATANBgkqhkiG9w0BAQEFAASCAQCHP/2nFqaDmpp4wnX/e/fT3fXONvQ0 aasoGe3eU+FhbJq9RKRQsS1DQRxihYwtdXzUZGiPjxnf+o1PprF9AiHTmTAzZLaiGaeVf57elONN mczMI5SHxPwT0ji11nXG8FYVnWMDZ4mpbJ8cLetPxHuJsza40lpXo49dJJfijHFmVoF+0T0GzwEu j7DrRSFmjWBmtlSpw+1hbA4pDolmHXrqu9QP+PteiRPrXQpCjY9fzO1+wFsv7dV1bkzBQxQw6e07 fxz527cpQ+DeRIob/6azWIVHRBbTYYyedxaZMv601IrgCBCVCPOWQzB/z7mFw1ejKkzJ4AYLvKuw 1lvU2kAt --0000000000002c23fb05af0d5af2--