All of lore.kernel.org
 help / color / mirror / Atom feed
From: Abel Vesa <abel.vesa@linaro.org>
To: "Peng Fan (OSS)" <peng.fan@oss.nxp.com>
Cc: abelvesa@kernel.org, mturquette@baylibre.com, sboyd@kernel.org,
	shawnguo@kernel.org, s.hauer@pengutronix.de,
	kernel@pengutronix.de, festevam@gmail.com, robh+dt@kernel.org,
	krzysztof.kozlowski+dt@linaro.org, linux-imx@nxp.com,
	linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	Peng Fan <peng.fan@nxp.com>
Subject: Re: [PATCH V3 3/7] clk: imx: fracn-gppll: support integer pll
Date: Sun, 9 Apr 2023 16:45:36 +0300	[thread overview]
Message-ID: <ZDLBgBjGSuNTKfWN@linaro.org> (raw)
In-Reply-To: <20230403095300.3386988-4-peng.fan@oss.nxp.com>

On 23-04-03 17:52:56, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
> 
> The fracn gppll could be configured in FRAC or INTEGER mode during
> hardware design. The current driver only support FRAC mode, while
> this patch introduces INTEGER support. When the PLL is INTEGER pll,
> there is no mfn, mfd, the calculation is as below:
>  Fvco_clk = (Fref / DIV[RDIV] ) * DIV[MFI]
>  Fclko_odiv = Fvco_clk / DIV[ODIV]
> 
> In this patch, we reuse the FRAC pll logic with some condition check to
> simplify the driver
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---

Reviewed-by: Abel Vesa <abel.vesa@linaro.org>

>  drivers/clk/imx/clk-fracn-gppll.c | 68 +++++++++++++++++++++++++++----
>  drivers/clk/imx/clk.h             |  7 ++++
>  2 files changed, 68 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
> index f6674110a88e..e2633ad94640 100644
> --- a/drivers/clk/imx/clk-fracn-gppll.c
> +++ b/drivers/clk/imx/clk-fracn-gppll.c
> @@ -53,11 +53,22 @@
>  		.odiv	=	(_odiv),			\
>  	}
>  
> +#define PLL_FRACN_GP_INTEGER(_rate, _mfi, _rdiv, _odiv)		\
> +	{							\
> +		.rate	=	(_rate),			\
> +		.mfi	=	(_mfi),				\
> +		.mfn	=	0,				\
> +		.mfd	=	0,				\
> +		.rdiv	=	(_rdiv),			\
> +		.odiv	=	(_odiv),			\
> +	}
> +
>  struct clk_fracn_gppll {
>  	struct clk_hw			hw;
>  	void __iomem			*base;
>  	const struct imx_fracn_gppll_rate_table *rate_table;
>  	int rate_count;
> +	u32 flags;
>  };
>  
>  /*
> @@ -83,6 +94,24 @@ struct imx_fracn_gppll_clk imx_fracn_gppll = {
>  };
>  EXPORT_SYMBOL_GPL(imx_fracn_gppll);
>  
> +/*
> + * Fvco = (Fref / rdiv) * MFI
> + * Fout = Fvco / odiv
> + * The (Fref / rdiv) should be in range 20MHz to 40MHz
> + * The Fvco should be in range 2.5Ghz to 5Ghz
> + */
> +static const struct imx_fracn_gppll_rate_table int_tbl[] = {
> +	PLL_FRACN_GP_INTEGER(1700000000U, 141, 1, 2),
> +	PLL_FRACN_GP_INTEGER(1400000000U, 175, 1, 3),
> +	PLL_FRACN_GP_INTEGER(900000000U, 150, 1, 4),
> +};
> +
> +struct imx_fracn_gppll_clk imx_fracn_gppll_integer = {
> +	.rate_table = int_tbl,
> +	.rate_count = ARRAY_SIZE(int_tbl),
> +};
> +EXPORT_SYMBOL_GPL(imx_fracn_gppll_integer);
> +
>  static inline struct clk_fracn_gppll *to_clk_fracn_gppll(struct clk_hw *hw)
>  {
>  	return container_of(hw, struct clk_fracn_gppll, hw);
> @@ -169,9 +198,15 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon
>  		break;
>  	}
>  
> -	/* Fvco = Fref * (MFI + MFN / MFD) */
> -	fvco = fvco * mfi * mfd + fvco * mfn;
> -	do_div(fvco, mfd * rdiv * odiv);
> +	if (pll->flags & CLK_FRACN_GPPLL_INTEGER) {
> +		/* Fvco = (Fref / rdiv) * MFI */
> +		fvco = fvco * mfi;
> +		do_div(fvco, rdiv * odiv);
> +	} else {
> +		/* Fvco = (Fref / rdiv) * (MFI + MFN / MFD) */
> +		fvco = fvco * mfi * mfd + fvco * mfn;
> +		do_div(fvco, mfd * rdiv * odiv);
> +	}
>  
>  	return (unsigned long)fvco;
>  }
> @@ -215,8 +250,10 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
>  	pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv |
>  		FIELD_PREP(PLL_MFI_MASK, rate->mfi);
>  	writel_relaxed(pll_div, pll->base + PLL_DIV);
> -	writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
> -	writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR);
> +	if (pll->flags & CLK_FRACN_GPPLL_FRACN) {
> +		writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
> +		writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR);
> +	}
>  
>  	/* Wait for 5us according to fracn mode pll doc */
>  	udelay(5);
> @@ -300,8 +337,10 @@ static const struct clk_ops clk_fracn_gppll_ops = {
>  	.set_rate	= clk_fracn_gppll_set_rate,
>  };
>  
> -struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
> -				   const struct imx_fracn_gppll_clk *pll_clk)
> +static struct clk_hw *_imx_clk_fracn_gppll(const char *name, const char *parent_name,
> +					   void __iomem *base,
> +					   const struct imx_fracn_gppll_clk *pll_clk,
> +					   u32 pll_flags)
>  {
>  	struct clk_fracn_gppll *pll;
>  	struct clk_hw *hw;
> @@ -322,6 +361,7 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
>  	pll->hw.init = &init;
>  	pll->rate_table = pll_clk->rate_table;
>  	pll->rate_count = pll_clk->rate_count;
> +	pll->flags = pll_flags;
>  
>  	hw = &pll->hw;
>  
> @@ -334,4 +374,18 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
>  
>  	return hw;
>  }
> +
> +struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
> +				   const struct imx_fracn_gppll_clk *pll_clk)
> +{
> +	return _imx_clk_fracn_gppll(name, parent_name, base, pll_clk, CLK_FRACN_GPPLL_FRACN);
> +}
>  EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll);
> +
> +struct clk_hw *imx_clk_fracn_gppll_integer(const char *name, const char *parent_name,
> +					   void __iomem *base,
> +					   const struct imx_fracn_gppll_clk *pll_clk)
> +{
> +	return _imx_clk_fracn_gppll(name, parent_name, base, pll_clk, CLK_FRACN_GPPLL_INTEGER);
> +}
> +EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll_integer);
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
> index 055bc9197fb4..cb4e4c4b8278 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -73,6 +73,9 @@ extern struct imx_pll14xx_clk imx_1416x_pll;
>  extern struct imx_pll14xx_clk imx_1443x_pll;
>  extern struct imx_pll14xx_clk imx_1443x_dram_pll;
>  
> +#define CLK_FRACN_GPPLL_INTEGER	BIT(0)
> +#define CLK_FRACN_GPPLL_FRACN	BIT(1)
> +
>  /* NOTE: Rate table should be kept sorted in descending order. */
>  struct imx_fracn_gppll_rate_table {
>  	unsigned int rate;
> @@ -91,8 +94,12 @@ struct imx_fracn_gppll_clk {
>  
>  struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
>  				   const struct imx_fracn_gppll_clk *pll_clk);
> +struct clk_hw *imx_clk_fracn_gppll_integer(const char *name, const char *parent_name,
> +					   void __iomem *base,
> +					   const struct imx_fracn_gppll_clk *pll_clk);
>  
>  extern struct imx_fracn_gppll_clk imx_fracn_gppll;
> +extern struct imx_fracn_gppll_clk imx_fracn_gppll_integer;
>  
>  #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
>  	to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
> -- 
> 2.37.1
> 

WARNING: multiple messages have this Message-ID (diff)
From: Abel Vesa <abel.vesa@linaro.org>
To: "Peng Fan (OSS)" <peng.fan@oss.nxp.com>
Cc: abelvesa@kernel.org, mturquette@baylibre.com, sboyd@kernel.org,
	shawnguo@kernel.org, s.hauer@pengutronix.de,
	kernel@pengutronix.de, festevam@gmail.com, robh+dt@kernel.org,
	krzysztof.kozlowski+dt@linaro.org, linux-imx@nxp.com,
	linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	Peng Fan <peng.fan@nxp.com>
Subject: Re: [PATCH V3 3/7] clk: imx: fracn-gppll: support integer pll
Date: Sun, 9 Apr 2023 16:45:36 +0300	[thread overview]
Message-ID: <ZDLBgBjGSuNTKfWN@linaro.org> (raw)
In-Reply-To: <20230403095300.3386988-4-peng.fan@oss.nxp.com>

On 23-04-03 17:52:56, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
> 
> The fracn gppll could be configured in FRAC or INTEGER mode during
> hardware design. The current driver only support FRAC mode, while
> this patch introduces INTEGER support. When the PLL is INTEGER pll,
> there is no mfn, mfd, the calculation is as below:
>  Fvco_clk = (Fref / DIV[RDIV] ) * DIV[MFI]
>  Fclko_odiv = Fvco_clk / DIV[ODIV]
> 
> In this patch, we reuse the FRAC pll logic with some condition check to
> simplify the driver
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---

Reviewed-by: Abel Vesa <abel.vesa@linaro.org>

>  drivers/clk/imx/clk-fracn-gppll.c | 68 +++++++++++++++++++++++++++----
>  drivers/clk/imx/clk.h             |  7 ++++
>  2 files changed, 68 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
> index f6674110a88e..e2633ad94640 100644
> --- a/drivers/clk/imx/clk-fracn-gppll.c
> +++ b/drivers/clk/imx/clk-fracn-gppll.c
> @@ -53,11 +53,22 @@
>  		.odiv	=	(_odiv),			\
>  	}
>  
> +#define PLL_FRACN_GP_INTEGER(_rate, _mfi, _rdiv, _odiv)		\
> +	{							\
> +		.rate	=	(_rate),			\
> +		.mfi	=	(_mfi),				\
> +		.mfn	=	0,				\
> +		.mfd	=	0,				\
> +		.rdiv	=	(_rdiv),			\
> +		.odiv	=	(_odiv),			\
> +	}
> +
>  struct clk_fracn_gppll {
>  	struct clk_hw			hw;
>  	void __iomem			*base;
>  	const struct imx_fracn_gppll_rate_table *rate_table;
>  	int rate_count;
> +	u32 flags;
>  };
>  
>  /*
> @@ -83,6 +94,24 @@ struct imx_fracn_gppll_clk imx_fracn_gppll = {
>  };
>  EXPORT_SYMBOL_GPL(imx_fracn_gppll);
>  
> +/*
> + * Fvco = (Fref / rdiv) * MFI
> + * Fout = Fvco / odiv
> + * The (Fref / rdiv) should be in range 20MHz to 40MHz
> + * The Fvco should be in range 2.5Ghz to 5Ghz
> + */
> +static const struct imx_fracn_gppll_rate_table int_tbl[] = {
> +	PLL_FRACN_GP_INTEGER(1700000000U, 141, 1, 2),
> +	PLL_FRACN_GP_INTEGER(1400000000U, 175, 1, 3),
> +	PLL_FRACN_GP_INTEGER(900000000U, 150, 1, 4),
> +};
> +
> +struct imx_fracn_gppll_clk imx_fracn_gppll_integer = {
> +	.rate_table = int_tbl,
> +	.rate_count = ARRAY_SIZE(int_tbl),
> +};
> +EXPORT_SYMBOL_GPL(imx_fracn_gppll_integer);
> +
>  static inline struct clk_fracn_gppll *to_clk_fracn_gppll(struct clk_hw *hw)
>  {
>  	return container_of(hw, struct clk_fracn_gppll, hw);
> @@ -169,9 +198,15 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon
>  		break;
>  	}
>  
> -	/* Fvco = Fref * (MFI + MFN / MFD) */
> -	fvco = fvco * mfi * mfd + fvco * mfn;
> -	do_div(fvco, mfd * rdiv * odiv);
> +	if (pll->flags & CLK_FRACN_GPPLL_INTEGER) {
> +		/* Fvco = (Fref / rdiv) * MFI */
> +		fvco = fvco * mfi;
> +		do_div(fvco, rdiv * odiv);
> +	} else {
> +		/* Fvco = (Fref / rdiv) * (MFI + MFN / MFD) */
> +		fvco = fvco * mfi * mfd + fvco * mfn;
> +		do_div(fvco, mfd * rdiv * odiv);
> +	}
>  
>  	return (unsigned long)fvco;
>  }
> @@ -215,8 +250,10 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
>  	pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv |
>  		FIELD_PREP(PLL_MFI_MASK, rate->mfi);
>  	writel_relaxed(pll_div, pll->base + PLL_DIV);
> -	writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
> -	writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR);
> +	if (pll->flags & CLK_FRACN_GPPLL_FRACN) {
> +		writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
> +		writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR);
> +	}
>  
>  	/* Wait for 5us according to fracn mode pll doc */
>  	udelay(5);
> @@ -300,8 +337,10 @@ static const struct clk_ops clk_fracn_gppll_ops = {
>  	.set_rate	= clk_fracn_gppll_set_rate,
>  };
>  
> -struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
> -				   const struct imx_fracn_gppll_clk *pll_clk)
> +static struct clk_hw *_imx_clk_fracn_gppll(const char *name, const char *parent_name,
> +					   void __iomem *base,
> +					   const struct imx_fracn_gppll_clk *pll_clk,
> +					   u32 pll_flags)
>  {
>  	struct clk_fracn_gppll *pll;
>  	struct clk_hw *hw;
> @@ -322,6 +361,7 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
>  	pll->hw.init = &init;
>  	pll->rate_table = pll_clk->rate_table;
>  	pll->rate_count = pll_clk->rate_count;
> +	pll->flags = pll_flags;
>  
>  	hw = &pll->hw;
>  
> @@ -334,4 +374,18 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
>  
>  	return hw;
>  }
> +
> +struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
> +				   const struct imx_fracn_gppll_clk *pll_clk)
> +{
> +	return _imx_clk_fracn_gppll(name, parent_name, base, pll_clk, CLK_FRACN_GPPLL_FRACN);
> +}
>  EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll);
> +
> +struct clk_hw *imx_clk_fracn_gppll_integer(const char *name, const char *parent_name,
> +					   void __iomem *base,
> +					   const struct imx_fracn_gppll_clk *pll_clk)
> +{
> +	return _imx_clk_fracn_gppll(name, parent_name, base, pll_clk, CLK_FRACN_GPPLL_INTEGER);
> +}
> +EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll_integer);
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
> index 055bc9197fb4..cb4e4c4b8278 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -73,6 +73,9 @@ extern struct imx_pll14xx_clk imx_1416x_pll;
>  extern struct imx_pll14xx_clk imx_1443x_pll;
>  extern struct imx_pll14xx_clk imx_1443x_dram_pll;
>  
> +#define CLK_FRACN_GPPLL_INTEGER	BIT(0)
> +#define CLK_FRACN_GPPLL_FRACN	BIT(1)
> +
>  /* NOTE: Rate table should be kept sorted in descending order. */
>  struct imx_fracn_gppll_rate_table {
>  	unsigned int rate;
> @@ -91,8 +94,12 @@ struct imx_fracn_gppll_clk {
>  
>  struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
>  				   const struct imx_fracn_gppll_clk *pll_clk);
> +struct clk_hw *imx_clk_fracn_gppll_integer(const char *name, const char *parent_name,
> +					   void __iomem *base,
> +					   const struct imx_fracn_gppll_clk *pll_clk);
>  
>  extern struct imx_fracn_gppll_clk imx_fracn_gppll;
> +extern struct imx_fracn_gppll_clk imx_fracn_gppll_integer;
>  
>  #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
>  	to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
> -- 
> 2.37.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2023-04-09 13:45 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-03  9:52 [PATCH V3 0/7] clk: imx: imx93: fix and update Peng Fan (OSS)
2023-04-03  9:52 ` Peng Fan (OSS)
2023-04-03  9:52 ` [PATCH V3 1/7] clk: imx: fracn-gppll: fix the rate table Peng Fan (OSS)
2023-04-03  9:52   ` Peng Fan (OSS)
2023-04-09 13:44   ` Abel Vesa
2023-04-09 13:44     ` Abel Vesa
2023-04-03  9:52 ` [PATCH V3 2/7] clk: imx: fracn-gppll: disable hardware select control Peng Fan (OSS)
2023-04-03  9:52   ` Peng Fan (OSS)
2023-04-09 13:44   ` Abel Vesa
2023-04-09 13:44     ` Abel Vesa
2023-04-03  9:52 ` [PATCH V3 3/7] clk: imx: fracn-gppll: support integer pll Peng Fan (OSS)
2023-04-03  9:52   ` Peng Fan (OSS)
2023-04-09 13:45   ` Abel Vesa [this message]
2023-04-09 13:45     ` Abel Vesa
2023-04-03  9:52 ` [PATCH V3 4/7] clk: imx: fracn-gppll: Add 300MHz freq support for imx9 Peng Fan (OSS)
2023-04-03  9:52   ` Peng Fan (OSS)
2023-04-09 13:46   ` Abel Vesa
2023-04-09 13:46     ` Abel Vesa
2023-04-03  9:52 ` [PATCH V3 5/7] clk: imx: imx93: add mcore_booted module paratemter Peng Fan (OSS)
2023-04-03  9:52   ` Peng Fan (OSS)
2023-04-09 13:46   ` Abel Vesa
2023-04-09 13:46     ` Abel Vesa
2023-04-03  9:52 ` [PATCH V3 6/7] dt-bindings: clock: imx93: add NIC, A55 and ARM PLL CLK Peng Fan (OSS)
2023-04-03  9:52   ` Peng Fan (OSS)
2023-04-03 10:32   ` Krzysztof Kozlowski
2023-04-03 10:32     ` Krzysztof Kozlowski
2023-04-03  9:53 ` [PATCH V3 7/7] clk: imx: imx93: Add nic and A55 clk Peng Fan (OSS)
2023-04-03  9:53   ` Peng Fan (OSS)
2023-04-09 13:47   ` Abel Vesa
2023-04-09 13:47     ` Abel Vesa
2023-04-09 13:53 ` [PATCH V3 0/7] clk: imx: imx93: fix and update Abel Vesa
2023-04-09 13:53   ` Abel Vesa

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=ZDLBgBjGSuNTKfWN@linaro.org \
    --to=abel.vesa@linaro.org \
    --cc=abelvesa@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=festevam@gmail.com \
    --cc=kernel@pengutronix.de \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-imx@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=peng.fan@nxp.com \
    --cc=peng.fan@oss.nxp.com \
    --cc=robh+dt@kernel.org \
    --cc=s.hauer@pengutronix.de \
    --cc=sboyd@kernel.org \
    --cc=shawnguo@kernel.org \
    /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.