Dne nedelja, 23. marec 2025 ob 12:35:12 Srednjeevropski standardni čas je Andre 
Przywara napisal(a):
> The Allwinner MMC code uses a complex C struct, modelling the clock
> device's register frame. We rely on sharing the member names across all
> Allwinner SoCs, which is fragile.
> 
> Drop the usage of the struct in the MMC code, by using #define'd
> register names and their offset, and then adding those names to the base
> pointer. This requires to define those offsets for all SoCs, but since we
> only use between four and six clock registers in the MMC code, this is
> easily done.
> 
> This removes one common user of the clock register struct.
> 
> Signed-off-by: Andre Przywara <andre.przyw...@arm.com>
> ---
>  arch/arm/include/asm/arch-sunxi/clock_sun4i.h |  6 ++++++
>  .../include/asm/arch-sunxi/clock_sun50i_h6.h  |  4 ++++
>  arch/arm/include/asm/arch-sunxi/clock_sun6i.h |  7 +++++++
>  .../include/asm/arch-sunxi/clock_sun8i_a83t.h |  7 +++++++
>  arch/arm/include/asm/arch-sunxi/clock_sun9i.h |  7 +++++++
>  drivers/mmc/sunxi_mmc.c                       | 20 +++++++++----------
>  6 files changed, 41 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h 
> b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
> index 2cec91cb20e..00bdd5f938d 100644
> --- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
> @@ -10,6 +10,12 @@
>  #ifndef _SUNXI_CLOCK_SUN4I_H
>  #define _SUNXI_CLOCK_SUN4I_H
>  
> +#define CCU_AHB_GATE0                0x60
> +#define CCU_MMC0_CLK_CFG     0x88
> +#define CCU_MMC1_CLK_CFG     0x8c
> +#define CCU_MMC2_CLK_CFG     0x90
> +#define CCU_MMC3_CLK_CFG     0x94
> +
>  struct sunxi_ccm_reg {
>       u32 pll1_cfg;           /* 0x00 pll1 control */
>       u32 pll1_tun;           /* 0x04 pll1 tuning */
> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h 
> b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
> index a485e00f1f3..655f562c2af 100644
> --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
> @@ -22,6 +22,10 @@
>  #define CCU_H6_APB1_CFG                      0x520
>  #define CCU_H6_APB2_CFG                      0x524
>  #define CCU_H6_MBUS_CFG                      0x540
> +#define CCU_MMC0_CLK_CFG             0x830
> +#define CCU_MMC1_CLK_CFG             0x834
> +#define CCU_MMC2_CLK_CFG             0x838
> +#define CCU_H6_MMC_GATE_RESET                0x84c
>  #define CCU_H6_UART_GATE_RESET               0x90c
>  #define CCU_H6_I2C_GATE_RESET                0x91c
>  
> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h 
> b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> index 7fcf340db69..28c3faccbbc 100644
> --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> @@ -10,6 +10,13 @@
>  #ifndef _SUNXI_CLOCK_SUN6I_H
>  #define _SUNXI_CLOCK_SUN6I_H
>  
> +#define CCU_AHB_GATE0                0x060
> +#define CCU_MMC0_CLK_CFG     0x088
> +#define CCU_MMC1_CLK_CFG     0x08c
> +#define CCU_MMC2_CLK_CFG     0x090
> +#define CCU_MMC3_CLK_CFG     0x094
> +#define CCU_AHB_RESET0_CFG   0x2c0
> +
>  struct sunxi_ccm_reg {
>       u32 pll1_cfg;           /* 0x00 pll1 control */
>       u32 reserved0;
> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun8i_a83t.h 
> b/arch/arm/include/asm/arch-sunxi/clock_sun8i_a83t.h
> index 35ca0491ac9..5ad2163926a 100644
> --- a/arch/arm/include/asm/arch-sunxi/clock_sun8i_a83t.h
> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun8i_a83t.h
> @@ -13,6 +13,13 @@
>  #ifndef _SUNXI_CLOCK_SUN8I_A83T_H
>  #define _SUNXI_CLOCK_SUN8I_A83T_H
>  
> +#define CCU_AHB_GATE0                0x060
> +#define CCU_MMC0_CLK_CFG     0x088
> +#define CCU_MMC1_CLK_CFG     0x08c
> +#define CCU_MMC2_CLK_CFG     0x090
> +#define CCU_MMC3_CLK_CFG     0x094
> +#define CCU_AHB_RESET0_CFG   0x2c0
> +
>  struct sunxi_ccm_reg {
>       u32 pll1_c0_cfg;        /* 0x00 c1cpu# pll control */
>       u32 pll1_c1_cfg;        /* 0x04 c1cpu# pll control */
> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h 
> b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
> index 006f7761fc6..8d696e533f8 100644
> --- a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
> @@ -12,6 +12,13 @@
>  #include <linux/bitops.h>
>  #endif
>  
> +#define CCU_MMC0_CLK_CFG     0x410
> +#define CCU_MMC1_CLK_CFG     0x414
> +#define CCU_MMC2_CLK_CFG     0x418
> +#define CCU_MMC3_CLK_CFG     0x41c
> +#define CCU_AHB_GATE0                0x580
> +#define CCU_AHB_RESET0_CFG   0x5a0
> +
>  struct sunxi_ccm_reg {
>       u32 pll1_c0_cfg;        /* 0x00 c0cpu# pll configuration */
>       u32 pll2_c1_cfg;        /* 0x04 c1cpu# pll configuration */
> diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
> index 0b56d1405be..432be66c632 100644
> --- a/drivers/mmc/sunxi_mmc.c
> +++ b/drivers/mmc/sunxi_mmc.c
> @@ -451,29 +451,29 @@ struct sunxi_mmc_priv mmc_host[4];
>  static int mmc_resource_init(int sdc_no)
>  {
>       struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
> -     struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +     void *ccm = (void *)SUNXI_CCM_BASE;
>  
>       debug("init mmc %d resource\n", sdc_no);
>  
>       switch (sdc_no) {
>       case 0:
>               priv->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
> -             priv->mclkreg = &ccm->sd0_clk_cfg;
> +             priv->mclkreg = ccm + CCU_MMC0_CLK_CFG;
>               break;
>       case 1:
>               priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
> -             priv->mclkreg = &ccm->sd1_clk_cfg;
> +             priv->mclkreg = ccm + CCU_MMC1_CLK_CFG;
>               break;
>  #ifdef SUNXI_MMC2_BASE
>       case 2:
>               priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
> -             priv->mclkreg = &ccm->sd2_clk_cfg;
> +             priv->mclkreg = ccm + CCU_MMC2_CLK_CFG;
>               break;
>  #endif
>  #ifdef SUNXI_MMC3_BASE
>       case 3:
>               priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
> -             priv->mclkreg = &ccm->sd3_clk_cfg;
> +             priv->mclkreg = ccm + CCU_MMC3_CLK_CFG;
>               break;
>  #endif
>       default:
> @@ -520,7 +520,7 @@ static const struct mmc_ops sunxi_mmc_ops = {
>  
>  struct mmc *sunxi_mmc_init(int sdc_no)
>  {
> -     struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +     void *ccm = (void *)SUNXI_CCM_BASE;
>       struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
>       struct mmc_config *cfg = &priv->cfg;
>       int ret;
> @@ -549,11 +549,11 @@ struct mmc *sunxi_mmc_init(int sdc_no)
>       /* config ahb clock */
>       debug("init mmc %d clock and io\n", sdc_no);
>  #if !defined(CONFIG_SUN50I_GEN_H6) && !defined(CONFIG_SUNXI_GEN_NCAT2)
> -     setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
> +     setbits_le32(ccm + CCU_AHB_GATE0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
>  
>  #ifdef CONFIG_SUNXI_GEN_SUN6I
>       /* unassert reset */
> -     setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
> +     setbits_le32(ccm + CCU_AHB_RESET0_CFG, 1 << 
> AHB_RESET_OFFSET_MMC(sdc_no));
>  #endif
>  #if defined(CONFIG_MACH_SUN9I)
>       /* sun9i has a mmc-common module, also set the gate and reset there */
> @@ -561,9 +561,9 @@ struct mmc *sunxi_mmc_init(int sdc_no)
>              SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
>  #endif
>  #else /* CONFIG_SUN50I_GEN_H6 */
> -     setbits_le32(&ccm->sd_gate_reset, 1 << sdc_no);
> +     setbits_le32(ccm + CCU_H6_MMC_GATE_RESET, 1 << sdc_no);
>       /* unassert reset */
> -     setbits_le32(&ccm->sd_gate_reset, 1 << (RESET_SHIFT + sdc_no));
> +     setbits_le32(ccm + CCU_H6_MMC_GATE_RESET, 1 << (RESET_SHIFT + sdc_no));

I guess this is in SPL path, so DT can't be used here? Anyway, can you use
some little more generic macro name? I assume there could be other generations
which can use same concept.

Best regards,
Jernej

>  #endif
>       ret = mmc_set_mod_clk(priv, 24000000);
>       if (ret)
> 




Reply via email to