xref: /linux/drivers/mmc/host/sdhci-pltfm.h (revision 0e748234293f5f2caa8dbd152caba5efb754c707)
1515033f9SAnton Vorontsov /*
2515033f9SAnton Vorontsov  * Copyright 2010 MontaVista Software, LLC.
3515033f9SAnton Vorontsov  *
4515033f9SAnton Vorontsov  * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
5515033f9SAnton Vorontsov  *
6515033f9SAnton Vorontsov  * This program is free software; you can redistribute it and/or modify
7515033f9SAnton Vorontsov  * it under the terms of the GNU General Public License version 2 as
8515033f9SAnton Vorontsov  * published by the Free Software Foundation.
9515033f9SAnton Vorontsov  */
10515033f9SAnton Vorontsov 
11515033f9SAnton Vorontsov #ifndef _DRIVERS_MMC_SDHCI_PLTFM_H
12515033f9SAnton Vorontsov #define _DRIVERS_MMC_SDHCI_PLTFM_H
13515033f9SAnton Vorontsov 
144b711cb1SWolfram Sang #include <linux/clk.h>
1585d6509dSShawn Guo #include <linux/platform_device.h>
16f0de8369SShawn Guo #include "sdhci.h"
1720b1597bSAnton Vorontsov 
1894cc6a86SShawn Guo struct sdhci_pltfm_data {
19ad1df8c2SLars-Peter Clausen 	const struct sdhci_ops *ops;
2094cc6a86SShawn Guo 	unsigned int quirks;
21ad82ab65SAl Cooper 	unsigned int quirks2;
2294cc6a86SShawn Guo };
2394cc6a86SShawn Guo 
244b711cb1SWolfram Sang struct sdhci_pltfm_host {
254b711cb1SWolfram Sang 	struct clk *clk;
26e149860dSRichard Zhu 	void *priv; /* to handle quirks across io-accessor calls */
27e307148fSShawn Guo 
28e307148fSShawn Guo 	/* migrate from sdhci_of_host */
29e307148fSShawn Guo 	unsigned int clock;
30e307148fSShawn Guo 	u16 xfer_mode_shadow;
31*0e748234SChristian Daudt 
32*0e748234SChristian Daudt 	unsigned long private[0] ____cacheline_aligned;
334b711cb1SWolfram Sang };
344b711cb1SWolfram Sang 
3538576af1SShawn Guo #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
36f0de8369SShawn Guo /*
37f0de8369SShawn Guo  * These accessors are designed for big endian hosts doing I/O to
38f0de8369SShawn Guo  * little endian controllers incorporating a 32-bit hardware byte swapper.
39f0de8369SShawn Guo  */
40f0de8369SShawn Guo static inline u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
41f0de8369SShawn Guo {
42f0de8369SShawn Guo 	return in_be32(host->ioaddr + reg);
43f0de8369SShawn Guo }
44f0de8369SShawn Guo 
45f0de8369SShawn Guo static inline u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
46f0de8369SShawn Guo {
47f0de8369SShawn Guo 	return in_be16(host->ioaddr + (reg ^ 0x2));
48f0de8369SShawn Guo }
49f0de8369SShawn Guo 
50f0de8369SShawn Guo static inline u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
51f0de8369SShawn Guo {
52f0de8369SShawn Guo 	return in_8(host->ioaddr + (reg ^ 0x3));
53f0de8369SShawn Guo }
54f0de8369SShawn Guo 
55f0de8369SShawn Guo static inline void sdhci_be32bs_writel(struct sdhci_host *host,
56f0de8369SShawn Guo 				       u32 val, int reg)
57f0de8369SShawn Guo {
58f0de8369SShawn Guo 	out_be32(host->ioaddr + reg, val);
59f0de8369SShawn Guo }
60f0de8369SShawn Guo 
61f0de8369SShawn Guo static inline void sdhci_be32bs_writew(struct sdhci_host *host,
62f0de8369SShawn Guo 				       u16 val, int reg)
63f0de8369SShawn Guo {
64f0de8369SShawn Guo 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
65f0de8369SShawn Guo 	int base = reg & ~0x3;
66f0de8369SShawn Guo 	int shift = (reg & 0x2) * 8;
67f0de8369SShawn Guo 
68f0de8369SShawn Guo 	switch (reg) {
69f0de8369SShawn Guo 	case SDHCI_TRANSFER_MODE:
70f0de8369SShawn Guo 		/*
71f0de8369SShawn Guo 		 * Postpone this write, we must do it together with a
72f0de8369SShawn Guo 		 * command write that is down below.
73f0de8369SShawn Guo 		 */
74f0de8369SShawn Guo 		pltfm_host->xfer_mode_shadow = val;
75f0de8369SShawn Guo 		return;
76f0de8369SShawn Guo 	case SDHCI_COMMAND:
77f0de8369SShawn Guo 		sdhci_be32bs_writel(host,
78f0de8369SShawn Guo 				    val << 16 | pltfm_host->xfer_mode_shadow,
79f0de8369SShawn Guo 				    SDHCI_TRANSFER_MODE);
80f0de8369SShawn Guo 		return;
81f0de8369SShawn Guo 	}
82f0de8369SShawn Guo 	clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
83f0de8369SShawn Guo }
84f0de8369SShawn Guo 
85f0de8369SShawn Guo static inline void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
86f0de8369SShawn Guo {
87f0de8369SShawn Guo 	int base = reg & ~0x3;
88f0de8369SShawn Guo 	int shift = (reg & 0x3) * 8;
89f0de8369SShawn Guo 
90f0de8369SShawn Guo 	clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
91f0de8369SShawn Guo }
92f0de8369SShawn Guo #endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
9338576af1SShawn Guo 
9438576af1SShawn Guo extern void sdhci_get_of_property(struct platform_device *pdev);
9538576af1SShawn Guo 
9685d6509dSShawn Guo extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
97*0e748234SChristian Daudt 					  const struct sdhci_pltfm_data *pdata,
98*0e748234SChristian Daudt 					  size_t priv_size);
9985d6509dSShawn Guo extern void sdhci_pltfm_free(struct platform_device *pdev);
10085d6509dSShawn Guo 
10185d6509dSShawn Guo extern int sdhci_pltfm_register(struct platform_device *pdev,
102*0e748234SChristian Daudt 				const struct sdhci_pltfm_data *pdata,
103*0e748234SChristian Daudt 				size_t priv_size);
10485d6509dSShawn Guo extern int sdhci_pltfm_unregister(struct platform_device *pdev);
10585d6509dSShawn Guo 
106d005d943SLars-Peter Clausen extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
107d005d943SLars-Peter Clausen 
108*0e748234SChristian Daudt static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host)
109*0e748234SChristian Daudt {
110*0e748234SChristian Daudt 	return (void *)host->private;
111*0e748234SChristian Daudt }
112*0e748234SChristian Daudt 
11385d6509dSShawn Guo #ifdef CONFIG_PM
11429495aa0SManuel Lauss extern const struct dev_pm_ops sdhci_pltfm_pmops;
11529495aa0SManuel Lauss #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops)
11629495aa0SManuel Lauss #else
11729495aa0SManuel Lauss #define SDHCI_PLTFM_PMOPS NULL
11885d6509dSShawn Guo #endif
11920b1597bSAnton Vorontsov 
120515033f9SAnton Vorontsov #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */
121