diff mbox

[V2,2/4] mmc: sdhci-msm: Add msm version specific ops and data structures

Message ID 1527587561-27448-3-git-send-email-vviswana@codeaurora.org (mailing list archive)
State Not Applicable, archived
Delegated to: Andy Gross
Headers show

Commit Message

Vijay Viswanath May 29, 2018, 9:52 a.m. UTC
In addition to offsets of certain registers changing, the registers in
core_mem have been shifted to HC mem as well. To access these
registers, define msm version specific functions. These functions can
be loaded into the function pointers at the time of probe based on
the msm version detected.

Also defind new data structure to hold version specific Ops and
register addresses.

Signed-off-by: Sayali Lokhande <sayalil@codeaurora.org>
Signed-off-by: Vijay Viswanath <vviswana@codeaurora.org>
---
 drivers/mmc/host/sdhci-msm.c | 77 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

Comments

Adrian Hunter June 6, 2018, 6:31 a.m. UTC | #1
On 29/05/18 12:52, Vijay Viswanath wrote:
> In addition to offsets of certain registers changing, the registers in
> core_mem have been shifted to HC mem as well. To access these
> registers, define msm version specific functions. These functions can
> be loaded into the function pointers at the time of probe based on
> the msm version detected.
> 
> Also defind new data structure to hold version specific Ops and
> register addresses.
> 
> Signed-off-by: Sayali Lokhande <sayalil@codeaurora.org>
> Signed-off-by: Vijay Viswanath <vviswana@codeaurora.org>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  drivers/mmc/host/sdhci-msm.c | 77 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 77 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index 4050c99..2a66aa0 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -226,6 +226,24 @@ struct sdhci_msm_offset {
>  	.core_ddr_config_2 = 0x1bc,
>  };
>  
> +struct sdhci_msm_variant_ops {
> +	u8 (*msm_readb_relaxed)(struct sdhci_host *host, u32 offset);
> +	u32 (*msm_readl_relaxed)(struct sdhci_host *host, u32 offset);
> +	void (*msm_writeb_relaxed)(u8 val, struct sdhci_host *host, u32 offset);
> +	void (*msm_writel_relaxed)(u32 val, struct sdhci_host *host,
> +			u32 offset);
> +};
> +
> +/*
> + * From V5, register spaces have changed. Wrap this info in a structure
> + * and choose the data_structure based on version info mentioned in DT.
> + */
> +struct sdhci_msm_variant_info {
> +	bool mci_removed;
> +	const struct sdhci_msm_variant_ops *var_ops;
> +	const struct sdhci_msm_offset *offset;
> +};
> +
>  struct sdhci_msm_host {
>  	struct platform_device *pdev;
>  	void __iomem *core_mem;	/* MSM SDCC mapped address */
> @@ -245,8 +263,45 @@ struct sdhci_msm_host {
>  	wait_queue_head_t pwr_irq_wait;
>  	bool pwr_irq_flag;
>  	u32 caps_0;
> +	bool mci_removed;
> +	const struct sdhci_msm_variant_ops *var_ops;
> +	const struct sdhci_msm_offset *offset;
>  };
>  
> +/*
> + * APIs to read/write to vendor specific registers which were there in the
> + * core_mem region before MCI was removed.
> + */
> +static u32 sdhci_msm_mci_variant_readl_relaxed(struct sdhci_host *host,
> +		u32 offset)
> +{
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
> +
> +	return readl_relaxed(msm_host->core_mem + offset);
> +}
> +
> +static u32 sdhci_msm_v5_variant_readl_relaxed(struct sdhci_host *host,
> +		u32 offset)
> +{
> +	return readl_relaxed(host->ioaddr + offset);
> +}
> +
> +static void sdhci_msm_mci_variant_writel_relaxed(u32 val,
> +		struct sdhci_host *host, u32 offset)
> +{
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
> +
> +	writel_relaxed(val, msm_host->core_mem + offset);
> +}
> +
> +static void sdhci_msm_v5_variant_writel_relaxed(u32 val,
> +		struct sdhci_host *host, u32 offset)
> +{
> +	writel_relaxed(val, host->ioaddr + offset);
> +}
> +
>  static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host,
>  						    unsigned int clock)
>  {
> @@ -1481,6 +1536,28 @@ static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host)
>  	pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps);
>  }
>  
> +static const struct sdhci_msm_variant_ops mci_var_ops = {
> +	.msm_readl_relaxed = sdhci_msm_mci_variant_readl_relaxed,
> +	.msm_writel_relaxed = sdhci_msm_mci_variant_writel_relaxed,
> +};
> +
> +static const struct sdhci_msm_variant_ops v5_var_ops = {
> +	.msm_readl_relaxed = sdhci_msm_v5_variant_readl_relaxed,
> +	.msm_writel_relaxed = sdhci_msm_v5_variant_writel_relaxed,
> +};
> +
> +static const struct sdhci_msm_variant_info sdhci_msm_mci_var = {
> +	.mci_removed = 0,
> +	.var_ops = &mci_var_ops,
> +	.offset = &sdhci_msm_mci_offset,
> +};
> +
> +static const struct sdhci_msm_variant_info sdhci_msm_v5_var = {
> +	.mci_removed = 1,
> +	.var_ops = &v5_var_ops,
> +	.offset = &sdhci_msm_v5_offset,
> +};
> +
>  static const struct of_device_id sdhci_msm_dt_match[] = {
>  	{ .compatible = "qcom,sdhci-msm-v4" },
>  	{},
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Evan Green June 11, 2018, 9:23 p.m. UTC | #2
On Tue, Jun 5, 2018 at 11:32 PM Adrian Hunter <adrian.hunter@intel.com> wrote:
>
> On 29/05/18 12:52, Vijay Viswanath wrote:
> > In addition to offsets of certain registers changing, the registers in
> > core_mem have been shifted to HC mem as well. To access these
> > registers, define msm version specific functions. These functions can
> > be loaded into the function pointers at the time of probe based on
> > the msm version detected.
> >
> > Also defind new data structure to hold version specific Ops and
> > register addresses.
> >
> > Signed-off-by: Sayali Lokhande <sayalil@codeaurora.org>
> > Signed-off-by: Vijay Viswanath <vviswana@codeaurora.org>
>
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
>
> > ---
> >  drivers/mmc/host/sdhci-msm.c | 77 ++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 77 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> > index 4050c99..2a66aa0 100644
> > --- a/drivers/mmc/host/sdhci-msm.c
> > +++ b/drivers/mmc/host/sdhci-msm.c
> > @@ -226,6 +226,24 @@ struct sdhci_msm_offset {
> >       .core_ddr_config_2 = 0x1bc,
> >  };
> >
> > +struct sdhci_msm_variant_ops {
> > +     u8 (*msm_readb_relaxed)(struct sdhci_host *host, u32 offset);
> > +     u32 (*msm_readl_relaxed)(struct sdhci_host *host, u32 offset);
> > +     void (*msm_writeb_relaxed)(u8 val, struct sdhci_host *host, u32 offset);
> > +     void (*msm_writel_relaxed)(u32 val, struct sdhci_host *host,
> > +                     u32 offset);
> > +};

Since you removed the implementations, and these are also trivial to
re-derive, I'd suggest removing msm_readb_relaxed and
msm_writeb_relaxed members from the struct. Other than that, you can
add my Reviewed-by.
-Evan
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Stephen Boyd June 12, 2018, 11:36 p.m. UTC | #3
Quoting Vijay Viswanath (2018-05-29 02:52:39)
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index 4050c99..2a66aa0 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -226,6 +226,24 @@ struct sdhci_msm_offset {
>         .core_ddr_config_2 = 0x1bc,
>  };
>  
> +struct sdhci_msm_variant_ops {
> +       u8 (*msm_readb_relaxed)(struct sdhci_host *host, u32 offset);
> +       u32 (*msm_readl_relaxed)(struct sdhci_host *host, u32 offset);
> +       void (*msm_writeb_relaxed)(u8 val, struct sdhci_host *host, u32 offset);
> +       void (*msm_writel_relaxed)(u32 val, struct sdhci_host *host,
> +                       u32 offset);
> +};
> +
> +/*
> + * From V5, register spaces have changed. Wrap this info in a structure
> + * and choose the data_structure based on version info mentioned in DT.
> + */

This is sort of odd. Usually we have a read/write function that swizzles
based on register variants, and that's contained with that function. Now
it's the other way.

> +struct sdhci_msm_variant_info {
> +       bool mci_removed;
> +       const struct sdhci_msm_variant_ops *var_ops;
> +       const struct sdhci_msm_offset *offset;
> +};
> +
>  struct sdhci_msm_host {
>         struct platform_device *pdev;
>         void __iomem *core_mem; /* MSM SDCC mapped address */
> @@ -245,8 +263,45 @@ struct sdhci_msm_host {
>         wait_queue_head_t pwr_irq_wait;
>         bool pwr_irq_flag;
>         u32 caps_0;
> +       bool mci_removed;
> +       const struct sdhci_msm_variant_ops *var_ops;
> +       const struct sdhci_msm_offset *offset;
>  };
>  
> +/*
> + * APIs to read/write to vendor specific registers which were there in the
> + * core_mem region before MCI was removed.
> + */
> +static u32 sdhci_msm_mci_variant_readl_relaxed(struct sdhci_host *host,
> +               u32 offset)
> +{
> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +       struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
> +
> +       return readl_relaxed(msm_host->core_mem + offset);

Is core_mem assigned in the new hardware? Maybe that needs to be
'repurposed' for vendor specific registers on v5 and renamed to
something like msm_host::vendor_base or something like that.

> +}
> +
> +static u32 sdhci_msm_v5_variant_readl_relaxed(struct sdhci_host *host,
> +               u32 offset)
> +{
> +       return readl_relaxed(host->ioaddr + offset);
> +}
> +
> +static void sdhci_msm_mci_variant_writel_relaxed(u32 val,
> +               struct sdhci_host *host, u32 offset)
> +{
> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +       struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
> +
> +       writel_relaxed(val, msm_host->core_mem + offset);
> +}
> +
> +static void sdhci_msm_v5_variant_writel_relaxed(u32 val,
> +               struct sdhci_host *host, u32 offset)
> +{
> +       writel_relaxed(val, host->ioaddr + offset);
> +}
> +
>  static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host,
>                                                     unsigned int clock)
>  {
> @@ -1481,6 +1536,28 @@ static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host)
>         pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps);
>  }
>  
> +static const struct sdhci_msm_variant_ops mci_var_ops = {
> +       .msm_readl_relaxed = sdhci_msm_mci_variant_readl_relaxed,
> +       .msm_writel_relaxed = sdhci_msm_mci_variant_writel_relaxed,
> +};
> +
> +static const struct sdhci_msm_variant_ops v5_var_ops = {
> +       .msm_readl_relaxed = sdhci_msm_v5_variant_readl_relaxed,
> +       .msm_writel_relaxed = sdhci_msm_v5_variant_writel_relaxed,
> +};
> +
> +static const struct sdhci_msm_variant_info sdhci_msm_mci_var = {
> +       .mci_removed = 0,

Please use true and false instead of 0 and 1 when the type is bool.

> +       .var_ops = &mci_var_ops,
> +       .offset = &sdhci_msm_mci_offset,
> +};
> +
> +static const struct sdhci_msm_variant_info sdhci_msm_v5_var = {
> +       .mci_removed = 1,
> +       .var_ops = &v5_var_ops,
> +       .offset = &sdhci_msm_v5_offset,
> +};
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Vijay Viswanath June 15, 2018, 4:56 a.m. UTC | #4
Hi Stephen,

On 6/13/2018 5:06 AM, Stephen Boyd wrote:
> Quoting Vijay Viswanath (2018-05-29 02:52:39)
>> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
>> index 4050c99..2a66aa0 100644
>> --- a/drivers/mmc/host/sdhci-msm.c
>> +++ b/drivers/mmc/host/sdhci-msm.c
>> @@ -226,6 +226,24 @@ struct sdhci_msm_offset {
>>          .core_ddr_config_2 = 0x1bc,
>>   };
>>   
>> +struct sdhci_msm_variant_ops {
>> +       u8 (*msm_readb_relaxed)(struct sdhci_host *host, u32 offset);
>> +       u32 (*msm_readl_relaxed)(struct sdhci_host *host, u32 offset);
>> +       void (*msm_writeb_relaxed)(u8 val, struct sdhci_host *host, u32 offset);
>> +       void (*msm_writel_relaxed)(u32 val, struct sdhci_host *host,
>> +                       u32 offset);
>> +};
>> +
>> +/*
>> + * From V5, register spaces have changed. Wrap this info in a structure
>> + * and choose the data_structure based on version info mentioned in DT.
>> + */
> 
> This is sort of odd. Usually we have a read/write function that swizzles
> based on register variants, and that's contained with that function. Now
> it's the other way.
> 
>> +struct sdhci_msm_variant_info {
>> +       bool mci_removed;
>> +       const struct sdhci_msm_variant_ops *var_ops;
>> +       const struct sdhci_msm_offset *offset;
>> +};
>> +
>>   struct sdhci_msm_host {
>>          struct platform_device *pdev;
>>          void __iomem *core_mem; /* MSM SDCC mapped address */
>> @@ -245,8 +263,45 @@ struct sdhci_msm_host {
>>          wait_queue_head_t pwr_irq_wait;
>>          bool pwr_irq_flag;
>>          u32 caps_0;
>> +       bool mci_removed;
>> +       const struct sdhci_msm_variant_ops *var_ops;
>> +       const struct sdhci_msm_offset *offset;
>>   };
>>   
>> +/*
>> + * APIs to read/write to vendor specific registers which were there in the
>> + * core_mem region before MCI was removed.
>> + */
>> +static u32 sdhci_msm_mci_variant_readl_relaxed(struct sdhci_host *host,
>> +               u32 offset)
>> +{
>> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +       struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +       return readl_relaxed(msm_host->core_mem + offset);
> 
> Is core_mem assigned in the new hardware? Maybe that needs to be
> 'repurposed' for vendor specific registers on v5 and renamed to
> something like msm_host::vendor_base or something like that.
> 

There is no core_mem in the new hardware. We can assign hc_mem address 
to core_mem variable (if SDCC5) and do away with the need of special 
read/write functions, but I feel thats a bad approach and misleading.

>> +}
>> +
>> +static u32 sdhci_msm_v5_variant_readl_relaxed(struct sdhci_host *host,
>> +               u32 offset)
>> +{
>> +       return readl_relaxed(host->ioaddr + offset);
>> +}
>> +
>> +static void sdhci_msm_mci_variant_writel_relaxed(u32 val,
>> +               struct sdhci_host *host, u32 offset)
>> +{
>> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +       struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +       writel_relaxed(val, msm_host->core_mem + offset);
>> +}
>> +
>> +static void sdhci_msm_v5_variant_writel_relaxed(u32 val,
>> +               struct sdhci_host *host, u32 offset)
>> +{
>> +       writel_relaxed(val, host->ioaddr + offset);
>> +}
>> +
>>   static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host,
>>                                                      unsigned int clock)
>>   {
>> @@ -1481,6 +1536,28 @@ static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host)
>>          pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps);
>>   }
>>   
>> +static const struct sdhci_msm_variant_ops mci_var_ops = {
>> +       .msm_readl_relaxed = sdhci_msm_mci_variant_readl_relaxed,
>> +       .msm_writel_relaxed = sdhci_msm_mci_variant_writel_relaxed,
>> +};
>> +
>> +static const struct sdhci_msm_variant_ops v5_var_ops = {
>> +       .msm_readl_relaxed = sdhci_msm_v5_variant_readl_relaxed,
>> +       .msm_writel_relaxed = sdhci_msm_v5_variant_writel_relaxed,
>> +};
>> +
>> +static const struct sdhci_msm_variant_info sdhci_msm_mci_var = {
>> +       .mci_removed = 0,
> 
> Please use true and false instead of 0 and 1 when the type is bool.
>

Will do

>> +       .var_ops = &mci_var_ops,
>> +       .offset = &sdhci_msm_mci_offset,
>> +};
>> +
>> +static const struct sdhci_msm_variant_info sdhci_msm_v5_var = {
>> +       .mci_removed = 1,
>> +       .var_ops = &v5_var_ops,
>> +       .offset = &sdhci_msm_v5_offset,
>> +};
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 4050c99..2a66aa0 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -226,6 +226,24 @@  struct sdhci_msm_offset {
 	.core_ddr_config_2 = 0x1bc,
 };
 
+struct sdhci_msm_variant_ops {
+	u8 (*msm_readb_relaxed)(struct sdhci_host *host, u32 offset);
+	u32 (*msm_readl_relaxed)(struct sdhci_host *host, u32 offset);
+	void (*msm_writeb_relaxed)(u8 val, struct sdhci_host *host, u32 offset);
+	void (*msm_writel_relaxed)(u32 val, struct sdhci_host *host,
+			u32 offset);
+};
+
+/*
+ * From V5, register spaces have changed. Wrap this info in a structure
+ * and choose the data_structure based on version info mentioned in DT.
+ */
+struct sdhci_msm_variant_info {
+	bool mci_removed;
+	const struct sdhci_msm_variant_ops *var_ops;
+	const struct sdhci_msm_offset *offset;
+};
+
 struct sdhci_msm_host {
 	struct platform_device *pdev;
 	void __iomem *core_mem;	/* MSM SDCC mapped address */
@@ -245,8 +263,45 @@  struct sdhci_msm_host {
 	wait_queue_head_t pwr_irq_wait;
 	bool pwr_irq_flag;
 	u32 caps_0;
+	bool mci_removed;
+	const struct sdhci_msm_variant_ops *var_ops;
+	const struct sdhci_msm_offset *offset;
 };
 
+/*
+ * APIs to read/write to vendor specific registers which were there in the
+ * core_mem region before MCI was removed.
+ */
+static u32 sdhci_msm_mci_variant_readl_relaxed(struct sdhci_host *host,
+		u32 offset)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+
+	return readl_relaxed(msm_host->core_mem + offset);
+}
+
+static u32 sdhci_msm_v5_variant_readl_relaxed(struct sdhci_host *host,
+		u32 offset)
+{
+	return readl_relaxed(host->ioaddr + offset);
+}
+
+static void sdhci_msm_mci_variant_writel_relaxed(u32 val,
+		struct sdhci_host *host, u32 offset)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+
+	writel_relaxed(val, msm_host->core_mem + offset);
+}
+
+static void sdhci_msm_v5_variant_writel_relaxed(u32 val,
+		struct sdhci_host *host, u32 offset)
+{
+	writel_relaxed(val, host->ioaddr + offset);
+}
+
 static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host,
 						    unsigned int clock)
 {
@@ -1481,6 +1536,28 @@  static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host)
 	pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps);
 }
 
+static const struct sdhci_msm_variant_ops mci_var_ops = {
+	.msm_readl_relaxed = sdhci_msm_mci_variant_readl_relaxed,
+	.msm_writel_relaxed = sdhci_msm_mci_variant_writel_relaxed,
+};
+
+static const struct sdhci_msm_variant_ops v5_var_ops = {
+	.msm_readl_relaxed = sdhci_msm_v5_variant_readl_relaxed,
+	.msm_writel_relaxed = sdhci_msm_v5_variant_writel_relaxed,
+};
+
+static const struct sdhci_msm_variant_info sdhci_msm_mci_var = {
+	.mci_removed = 0,
+	.var_ops = &mci_var_ops,
+	.offset = &sdhci_msm_mci_offset,
+};
+
+static const struct sdhci_msm_variant_info sdhci_msm_v5_var = {
+	.mci_removed = 1,
+	.var_ops = &v5_var_ops,
+	.offset = &sdhci_msm_v5_offset,
+};
+
 static const struct of_device_id sdhci_msm_dt_match[] = {
 	{ .compatible = "qcom,sdhci-msm-v4" },
 	{},