All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
To: "Amadeusz Sławiński" <amadeuszx.slawinski@linux.intel.com>,
	broonie@kernel.org, alsa-devel@alsa-project.org
Cc: Sunil-kumar.Dommati@amd.com,
	open list <linux-kernel@vger.kernel.org>,
	Basavaraj.Hiregoudar@amd.com, Takashi Iwai <tiwai@suse.com>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Vijendar.Mukunda@amd.com, Alexander.Deucher@amd.com
Subject: Re: [PATCH v2 4/6] ASoC: amd: acp: Add ACP init()/deinit() callback for Renoir.
Date: Mon, 17 Jan 2022 17:20:25 +0530	[thread overview]
Message-ID: <85efbeec-6a63-9f34-d13a-2bdad327097f@amd.com> (raw)
In-Reply-To: <e815d582-bd7d-6ec0-05ca-97d633ef9e13@linux.intel.com>



On 1/14/2022 2:31 PM, Amadeusz Sławiński wrote:
> [CAUTION: External Email]
> 
> On 1/13/2022 5:33 PM, Ajit Kumar Pandey wrote:
>> ACP hardware has PGFSM control registers that can be configured to
>> power On/Off the ACP IP block. Add acp init()/de_init() callbacks
>> in renoir platform driver probe()/remove() respectively to power
>> on and off ACP IP block on ACP3X device.
>>
>> Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
>> ---
>>   sound/soc/amd/acp/acp-renoir.c       | 170 +++++++++++++++++++++++++++
>>   sound/soc/amd/acp/chip_offset_byte.h |   6 +
>>   2 files changed, 176 insertions(+)
>>
>> diff --git a/sound/soc/amd/acp/acp-renoir.c 
>> b/sound/soc/amd/acp/acp-renoir.c
>> index 770a57a0677b..a29f910f25d1 100644
>> --- a/sound/soc/amd/acp/acp-renoir.c
>> +++ b/sound/soc/amd/acp/acp-renoir.c
>> @@ -25,6 +25,19 @@
>>
>>   #define DRV_NAME "acp_asoc_renoir"
>>
>> +#define ACP_SOFT_RST_DONE_MASK       0x00010001
>> +
>> +#define ACP_PWR_ON_MASK              0x01
>> +#define ACP_PWR_OFF_MASK     0x00
>> +#define ACP_PGFSM_STAT_MASK  0x03
>> +#define ACP_POWERED_ON               0x00
>> +#define ACP_PWR_ON_IN_PROGRESS       0x01
>> +#define ACP_POWERED_OFF              0x02
>> +
>> +
>> +#define ACP_ERROR_MASK 0x20000000
>> +#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
>> +
>>   static struct snd_soc_acpi_codecs amp_rt1019 = {
>>       .num_codecs = 1,
>>       .codecs = {"10EC1019"}
>> @@ -112,11 +125,154 @@ static struct snd_soc_dai_driver 
>> acp_renoir_dai[] = {
>>   },
>>   };
>>
>> +static int acp3x_power_on(void __iomem *base)
>> +{
>> +     u32 val;
>> +     int timeout = 0;
>> +
>> +     val = readl(base + ACP_PGFSM_STATUS);
>> +
>> +     if (val == ACP_POWERED_ON)
>> +             return 0;
>> +
>> +     if ((val & ACP_PGFSM_STAT_MASK) != ACP_PWR_ON_IN_PROGRESS)
>> +             writel(ACP_PWR_ON_MASK, base + ACP_PGFSM_CONTROL);
>> +
>> +     while (++timeout < 500) {
>> +             val = readl(base + ACP_PGFSM_STATUS);
>> +             if (!val)
>> +                     return 0;
>> +             udelay(1);
>> +     }
> 
> Can this while loop perhaps be replaced with readl_poll_timeout?
> Similarly for cases below?
> 
>> +
>> +     return -ETIMEDOUT;
>> +}
>> +
>> +static int acp3x_power_off(void __iomem *base)
>> +{
>> +     u32 val;
>> +     int timeout = 0;
>> +
>> +     writel(ACP_PWR_OFF_MASK, base + ACP_PGFSM_CONTROL);
>> +
>> +     while (++timeout < 500) {
>> +             val = readl(base + ACP_PGFSM_STATUS);
>> +             if ((val & ACP_PGFSM_STAT_MASK) == ACP_POWERED_OFF)
>> +                     return 0;
>> +             udelay(1);
>> +     }
>> +
>> +     return -ETIMEDOUT;
>> +}
>> +
>> +static int acp3x_reset(void __iomem *base)
>> +{
>> +     u32 val;
>> +     int timeout = 0;
>> +
>> +     writel(1, base + ACP_SOFT_RESET);
>> +
>> +     while (++timeout < 500) {
>> +             val = readl(base + ACP_SOFT_RESET);
>> +             if (val & ACP_SOFT_RST_DONE_MASK)
>> +                     break;
>> +             cpu_relax();
>> +     }
>> +
>> +     writel(0, base + ACP_SOFT_RESET);
>> +
>> +     timeout = 0;
>> +     while (++timeout < 500) {
>> +             val = readl(base + ACP_SOFT_RESET);
>> +             if (!val)
>> +                     return 0;
>> +             cpu_relax();
>> +     }
>> +
>> +     return -ETIMEDOUT;
>> +}
>> +
>> +static void acp3x_enable_interrupts(void __iomem *base)
>> +{
>> +     u32 ext_intr_ctrl;
>> +
>> +     writel(0x01, base + ACP_EXTERNAL_INTR_ENB);
>> +     ext_intr_ctrl = readl(base + ACP_EXTERNAL_INTR_CNTL);
>> +     ext_intr_ctrl |= ACP_ERROR_MASK;
>> +     writel(ext_intr_ctrl, base + ACP_EXTERNAL_INTR_CNTL);
>> +}
>> +
>> +static void acp3x_disable_interrupts(void __iomem *base)
>> +{
>> +     writel(ACP_EXT_INTR_STAT_CLEAR_MASK, base + 
>> ACP_EXTERNAL_INTR_STAT);
>> +     writel(0x00, base + ACP_EXTERNAL_INTR_ENB);
>> +}
>> +
>> +static int rn_acp_init(void __iomem *base)
>> +{
>> +     int ret;
>> +
>> +     /* power on */
>> +     ret = acp3x_power_on(base);
>> +     if (ret)
>> +             return ret;
>> +
>> +     writel(0x01, base + ACP_CONTROL);
>> +
>> +     /* Reset */
>> +     ret = acp3x_reset(base);
>> +     if (ret)
>> +             return ret;
>> +
>> +     acp3x_enable_interrupts(base);
>> +
>> +     return 0;
>> +}
>> +
>> +static int rn_acp_deinit(void __iomem *base)
>> +{
>> +     int ret = 0;
>> +
>> +     acp3x_disable_interrupts(base);
>> +
>> +     /* Reset */
>> +     ret = acp3x_reset(base);
>> +     if (ret)
>> +             return ret;
>> +
>> +     writel(0x00, base + ACP_CONTROL);
>> +
>> +     /* power off */
>> +     ret = acp3x_power_off(base);
>> +     if (ret)
>> +             return ret;
>> +
>> +     return 0;
>> +}
>>   static int renoir_audio_probe(struct platform_device *pdev)
>>   {
>>       struct device *dev = &pdev->dev;
>> +     struct acp_chip_info *chip;
>>       struct acp_dev_data *adata;
>>       struct resource *res;
>> +     int ret;
>> +
>> +     chip = dev_get_platdata(&pdev->dev);
>> +     if (!chip || !chip->base) {
>> +             dev_err(&pdev->dev, "ACP chip data is NULL\n");
>> +             return -ENODEV;
>> +     }
>> +
>> +     if (chip->acp_rev != ACP3X_DEV) {
>> +             dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", 
>> chip->acp_rev);
>> +             return -ENODEV;
>> +     }
>> +
>> +     ret = rn_acp_init(chip->base);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "ACP Init failed\n");
>> +             return -EINVAL;
>> +     }
>>
>>       adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
>>       if (!adata)
>> @@ -155,6 +311,20 @@ static int renoir_audio_probe(struct 
>> platform_device *pdev)
>>   static int renoir_audio_remove(struct platform_device *pdev)
>>   {
>>       struct device *dev = &pdev->dev;
>> +     struct acp_chip_info *chip;
>> +     int ret;
>> +
>> +     chip = dev_get_platdata(&pdev->dev);
>> +     if (!chip || !chip->base) {
>> +             dev_err(&pdev->dev, "ACP chip data is NULL\n");
>> +             return -ENODEV;
>> +     }
>> +
>> +     ret = rn_acp_deinit(chip->base);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "ACP de-init Failed\n");
>> +             return -EINVAL;
>> +     }
>>
>>       acp_platform_unregister(dev);
>>       return 0;
>> diff --git a/sound/soc/amd/acp/chip_offset_byte.h 
>> b/sound/soc/amd/acp/chip_offset_byte.h
>> index e38589a142e9..88f6fa597cd6 100644
>> --- a/sound/soc/amd/acp/chip_offset_byte.h
>> +++ b/sound/soc/amd/acp/chip_offset_byte.h
>> @@ -14,6 +14,12 @@
>>   #define ACPAXI2AXI_ATU_CTRL                           0xC40
>>   #define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5                0xC20
>>   #define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5                0xC24
>> +
>> +#define ACP_PGFSM_CONTROL                    0x141C
>> +#define ACP_PGFSM_STATUS                        0x1420
>> +#define ACP_SOFT_RESET                          0x1000
>> +#define ACP_CONTROL                             0x1004
>> +
>>   #define ACP_EXTERNAL_INTR_ENB                         0x1800
>>   #define ACP_EXTERNAL_INTR_CNTL                        0x1804
>>   #define ACP_EXTERNAL_INTR_STAT                        0x1808
> 
ok will improvise this in next patch chain

WARNING: multiple messages have this Message-ID (diff)
From: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
To: "Amadeusz Sławiński" <amadeuszx.slawinski@linux.intel.com>,
	broonie@kernel.org, alsa-devel@alsa-project.org
Cc: Sunil-kumar.Dommati@amd.com, Basavaraj.Hiregoudar@amd.com,
	Takashi Iwai <tiwai@suse.com>,
	Liam Girdwood <lgirdwood@gmail.com>,
	open list <linux-kernel@vger.kernel.org>,
	Vijendar.Mukunda@amd.com, Alexander.Deucher@amd.com
Subject: Re: [PATCH v2 4/6] ASoC: amd: acp: Add ACP init()/deinit() callback for Renoir.
Date: Mon, 17 Jan 2022 17:20:25 +0530	[thread overview]
Message-ID: <85efbeec-6a63-9f34-d13a-2bdad327097f@amd.com> (raw)
In-Reply-To: <e815d582-bd7d-6ec0-05ca-97d633ef9e13@linux.intel.com>



On 1/14/2022 2:31 PM, Amadeusz Sławiński wrote:
> [CAUTION: External Email]
> 
> On 1/13/2022 5:33 PM, Ajit Kumar Pandey wrote:
>> ACP hardware has PGFSM control registers that can be configured to
>> power On/Off the ACP IP block. Add acp init()/de_init() callbacks
>> in renoir platform driver probe()/remove() respectively to power
>> on and off ACP IP block on ACP3X device.
>>
>> Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
>> ---
>>   sound/soc/amd/acp/acp-renoir.c       | 170 +++++++++++++++++++++++++++
>>   sound/soc/amd/acp/chip_offset_byte.h |   6 +
>>   2 files changed, 176 insertions(+)
>>
>> diff --git a/sound/soc/amd/acp/acp-renoir.c 
>> b/sound/soc/amd/acp/acp-renoir.c
>> index 770a57a0677b..a29f910f25d1 100644
>> --- a/sound/soc/amd/acp/acp-renoir.c
>> +++ b/sound/soc/amd/acp/acp-renoir.c
>> @@ -25,6 +25,19 @@
>>
>>   #define DRV_NAME "acp_asoc_renoir"
>>
>> +#define ACP_SOFT_RST_DONE_MASK       0x00010001
>> +
>> +#define ACP_PWR_ON_MASK              0x01
>> +#define ACP_PWR_OFF_MASK     0x00
>> +#define ACP_PGFSM_STAT_MASK  0x03
>> +#define ACP_POWERED_ON               0x00
>> +#define ACP_PWR_ON_IN_PROGRESS       0x01
>> +#define ACP_POWERED_OFF              0x02
>> +
>> +
>> +#define ACP_ERROR_MASK 0x20000000
>> +#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
>> +
>>   static struct snd_soc_acpi_codecs amp_rt1019 = {
>>       .num_codecs = 1,
>>       .codecs = {"10EC1019"}
>> @@ -112,11 +125,154 @@ static struct snd_soc_dai_driver 
>> acp_renoir_dai[] = {
>>   },
>>   };
>>
>> +static int acp3x_power_on(void __iomem *base)
>> +{
>> +     u32 val;
>> +     int timeout = 0;
>> +
>> +     val = readl(base + ACP_PGFSM_STATUS);
>> +
>> +     if (val == ACP_POWERED_ON)
>> +             return 0;
>> +
>> +     if ((val & ACP_PGFSM_STAT_MASK) != ACP_PWR_ON_IN_PROGRESS)
>> +             writel(ACP_PWR_ON_MASK, base + ACP_PGFSM_CONTROL);
>> +
>> +     while (++timeout < 500) {
>> +             val = readl(base + ACP_PGFSM_STATUS);
>> +             if (!val)
>> +                     return 0;
>> +             udelay(1);
>> +     }
> 
> Can this while loop perhaps be replaced with readl_poll_timeout?
> Similarly for cases below?
> 
>> +
>> +     return -ETIMEDOUT;
>> +}
>> +
>> +static int acp3x_power_off(void __iomem *base)
>> +{
>> +     u32 val;
>> +     int timeout = 0;
>> +
>> +     writel(ACP_PWR_OFF_MASK, base + ACP_PGFSM_CONTROL);
>> +
>> +     while (++timeout < 500) {
>> +             val = readl(base + ACP_PGFSM_STATUS);
>> +             if ((val & ACP_PGFSM_STAT_MASK) == ACP_POWERED_OFF)
>> +                     return 0;
>> +             udelay(1);
>> +     }
>> +
>> +     return -ETIMEDOUT;
>> +}
>> +
>> +static int acp3x_reset(void __iomem *base)
>> +{
>> +     u32 val;
>> +     int timeout = 0;
>> +
>> +     writel(1, base + ACP_SOFT_RESET);
>> +
>> +     while (++timeout < 500) {
>> +             val = readl(base + ACP_SOFT_RESET);
>> +             if (val & ACP_SOFT_RST_DONE_MASK)
>> +                     break;
>> +             cpu_relax();
>> +     }
>> +
>> +     writel(0, base + ACP_SOFT_RESET);
>> +
>> +     timeout = 0;
>> +     while (++timeout < 500) {
>> +             val = readl(base + ACP_SOFT_RESET);
>> +             if (!val)
>> +                     return 0;
>> +             cpu_relax();
>> +     }
>> +
>> +     return -ETIMEDOUT;
>> +}
>> +
>> +static void acp3x_enable_interrupts(void __iomem *base)
>> +{
>> +     u32 ext_intr_ctrl;
>> +
>> +     writel(0x01, base + ACP_EXTERNAL_INTR_ENB);
>> +     ext_intr_ctrl = readl(base + ACP_EXTERNAL_INTR_CNTL);
>> +     ext_intr_ctrl |= ACP_ERROR_MASK;
>> +     writel(ext_intr_ctrl, base + ACP_EXTERNAL_INTR_CNTL);
>> +}
>> +
>> +static void acp3x_disable_interrupts(void __iomem *base)
>> +{
>> +     writel(ACP_EXT_INTR_STAT_CLEAR_MASK, base + 
>> ACP_EXTERNAL_INTR_STAT);
>> +     writel(0x00, base + ACP_EXTERNAL_INTR_ENB);
>> +}
>> +
>> +static int rn_acp_init(void __iomem *base)
>> +{
>> +     int ret;
>> +
>> +     /* power on */
>> +     ret = acp3x_power_on(base);
>> +     if (ret)
>> +             return ret;
>> +
>> +     writel(0x01, base + ACP_CONTROL);
>> +
>> +     /* Reset */
>> +     ret = acp3x_reset(base);
>> +     if (ret)
>> +             return ret;
>> +
>> +     acp3x_enable_interrupts(base);
>> +
>> +     return 0;
>> +}
>> +
>> +static int rn_acp_deinit(void __iomem *base)
>> +{
>> +     int ret = 0;
>> +
>> +     acp3x_disable_interrupts(base);
>> +
>> +     /* Reset */
>> +     ret = acp3x_reset(base);
>> +     if (ret)
>> +             return ret;
>> +
>> +     writel(0x00, base + ACP_CONTROL);
>> +
>> +     /* power off */
>> +     ret = acp3x_power_off(base);
>> +     if (ret)
>> +             return ret;
>> +
>> +     return 0;
>> +}
>>   static int renoir_audio_probe(struct platform_device *pdev)
>>   {
>>       struct device *dev = &pdev->dev;
>> +     struct acp_chip_info *chip;
>>       struct acp_dev_data *adata;
>>       struct resource *res;
>> +     int ret;
>> +
>> +     chip = dev_get_platdata(&pdev->dev);
>> +     if (!chip || !chip->base) {
>> +             dev_err(&pdev->dev, "ACP chip data is NULL\n");
>> +             return -ENODEV;
>> +     }
>> +
>> +     if (chip->acp_rev != ACP3X_DEV) {
>> +             dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", 
>> chip->acp_rev);
>> +             return -ENODEV;
>> +     }
>> +
>> +     ret = rn_acp_init(chip->base);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "ACP Init failed\n");
>> +             return -EINVAL;
>> +     }
>>
>>       adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
>>       if (!adata)
>> @@ -155,6 +311,20 @@ static int renoir_audio_probe(struct 
>> platform_device *pdev)
>>   static int renoir_audio_remove(struct platform_device *pdev)
>>   {
>>       struct device *dev = &pdev->dev;
>> +     struct acp_chip_info *chip;
>> +     int ret;
>> +
>> +     chip = dev_get_platdata(&pdev->dev);
>> +     if (!chip || !chip->base) {
>> +             dev_err(&pdev->dev, "ACP chip data is NULL\n");
>> +             return -ENODEV;
>> +     }
>> +
>> +     ret = rn_acp_deinit(chip->base);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "ACP de-init Failed\n");
>> +             return -EINVAL;
>> +     }
>>
>>       acp_platform_unregister(dev);
>>       return 0;
>> diff --git a/sound/soc/amd/acp/chip_offset_byte.h 
>> b/sound/soc/amd/acp/chip_offset_byte.h
>> index e38589a142e9..88f6fa597cd6 100644
>> --- a/sound/soc/amd/acp/chip_offset_byte.h
>> +++ b/sound/soc/amd/acp/chip_offset_byte.h
>> @@ -14,6 +14,12 @@
>>   #define ACPAXI2AXI_ATU_CTRL                           0xC40
>>   #define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5                0xC20
>>   #define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5                0xC24
>> +
>> +#define ACP_PGFSM_CONTROL                    0x141C
>> +#define ACP_PGFSM_STATUS                        0x1420
>> +#define ACP_SOFT_RESET                          0x1000
>> +#define ACP_CONTROL                             0x1004
>> +
>>   #define ACP_EXTERNAL_INTR_ENB                         0x1800
>>   #define ACP_EXTERNAL_INTR_CNTL                        0x1804
>>   #define ACP_EXTERNAL_INTR_STAT                        0x1808
> 
ok will improvise this in next patch chain

  reply	other threads:[~2022-01-17 11:50 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-13 16:33 [PATCH v2 0/6] ASOC: amd: acp: Add generic PDM and PCI driver support for ACP Ajit Kumar Pandey
2022-01-13 16:33 ` [PATCH v2 1/6] ASoC: amd: acp: Add generic support for PDM controller on ACP Ajit Kumar Pandey
2022-01-13 16:33   ` Ajit Kumar Pandey
2022-01-13 18:34   ` Pierre-Louis Bossart
2022-01-13 18:34     ` Pierre-Louis Bossart
2022-01-17 11:48     ` Ajit Kumar Pandey
2022-01-17 11:48       ` Ajit Kumar Pandey
2022-01-13 16:33 ` [PATCH v2 2/6] ASoC: amd: acp: Add PDM controller based dmic dai for Renoir Ajit Kumar Pandey
2022-01-13 16:33   ` Ajit Kumar Pandey
2022-01-13 16:33 ` [PATCH v2 3/6] ASoC: amd: acp: Add generic PCI driver module for ACP device Ajit Kumar Pandey
2022-01-13 16:33   ` Ajit Kumar Pandey
2022-01-13 18:36   ` Pierre-Louis Bossart
2022-01-13 18:36     ` Pierre-Louis Bossart
2022-01-13 16:33 ` [PATCH v2 4/6] ASoC: amd: acp: Add ACP init()/deinit() callback for Renoir Ajit Kumar Pandey
2022-01-13 16:33   ` Ajit Kumar Pandey
2022-01-14  9:01   ` Amadeusz Sławiński
2022-01-14  9:01     ` Amadeusz Sławiński
2022-01-17 11:50     ` Ajit Kumar Pandey [this message]
2022-01-17 11:50       ` Ajit Kumar Pandey
2022-01-13 16:33 ` [PATCH v2 5/6] ASoC: amd: acp: acp-legacy: Add DMIC dai link support " Ajit Kumar Pandey
2022-01-13 16:33   ` Ajit Kumar Pandey
2022-01-13 18:38   ` Pierre-Louis Bossart
2022-01-13 18:38     ` Pierre-Louis Bossart
2022-01-13 16:33 ` [PATCH v2 6/6] ASoC: amd: renoir: Add check for acp configuration flags Ajit Kumar Pandey
2022-01-13 16:33   ` Ajit Kumar Pandey
2022-01-16 22:55   ` kernel test robot
2022-01-17  5:12   ` kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=85efbeec-6a63-9f34-d13a-2bdad327097f@amd.com \
    --to=ajitkumar.pandey@amd.com \
    --cc=Alexander.Deucher@amd.com \
    --cc=Basavaraj.Hiregoudar@amd.com \
    --cc=Sunil-kumar.Dommati@amd.com \
    --cc=Vijendar.Mukunda@amd.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=amadeuszx.slawinski@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.