aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben.dooks@codethink.co.uk>2015-03-25 07:27:52 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2015-04-09 03:08:15 -0400
commit76184ac17edf3c640390b0eddc3aa7be1095fb9f (patch)
tree6de305bc6530a70b743c2a9262c88628ff36da8f
parent6687c42fa71acd6ae39608c5af4146c82bd0c0ea (diff)
mmc: dw_mmc: fix fifo ordering in big endian
The dw_mmc driver changes to make the IO accesors endian agnostic did not take into account the fifo accesses do not need to be swapped. To fix this add a mmci_fifo_read/write wrapper to allow these to be passed through the IO without being swapped. Since these are now specific functions, it would be easier just to store the pointer to the fifo registers in the host block instead of the offset to them. So change the host->data_offset to host->fifo_reg (which also means we catch all the places this is read or written). Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/mmc/host/dw_mmc.c59
-rw-r--r--drivers/mmc/host/dw_mmc.h14
-rw-r--r--include/linux/mmc/dw_mmc.h4
3 files changed, 40 insertions, 37 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index a09840d0c221..8ce9a52d365b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1757,8 +1757,7 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt)
1757 buf += len; 1757 buf += len;
1758 cnt -= len; 1758 cnt -= len;
1759 if (host->part_buf_count == 2) { 1759 if (host->part_buf_count == 2) {
1760 mci_writew(host, DATA(host->data_offset), 1760 mci_fifo_writew(host->fifo_reg, host->part_buf16);
1761 host->part_buf16);
1762 host->part_buf_count = 0; 1761 host->part_buf_count = 0;
1763 } 1762 }
1764 } 1763 }
@@ -1775,15 +1774,14 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt)
1775 cnt -= len; 1774 cnt -= len;
1776 /* push data from aligned buffer into fifo */ 1775 /* push data from aligned buffer into fifo */
1777 for (i = 0; i < items; ++i) 1776 for (i = 0; i < items; ++i)
1778 mci_writew(host, DATA(host->data_offset), 1777 mci_fifo_writew(host->fifo_reg, aligned_buf[i]);
1779 aligned_buf[i]);
1780 } 1778 }
1781 } else 1779 } else
1782#endif 1780#endif
1783 { 1781 {
1784 u16 *pdata = buf; 1782 u16 *pdata = buf;
1785 for (; cnt >= 2; cnt -= 2) 1783 for (; cnt >= 2; cnt -= 2)
1786 mci_writew(host, DATA(host->data_offset), *pdata++); 1784 mci_fifo_writew(host->fifo_reg, *pdata++);
1787 buf = pdata; 1785 buf = pdata;
1788 } 1786 }
1789 /* put anything remaining in the part_buf */ 1787 /* put anything remaining in the part_buf */
@@ -1792,8 +1790,7 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt)
1792 /* Push data if we have reached the expected data length */ 1790 /* Push data if we have reached the expected data length */
1793 if ((data->bytes_xfered + init_cnt) == 1791 if ((data->bytes_xfered + init_cnt) ==
1794 (data->blksz * data->blocks)) 1792 (data->blksz * data->blocks))
1795 mci_writew(host, DATA(host->data_offset), 1793 mci_fifo_writew(host->fifo_reg, host->part_buf16);
1796 host->part_buf16);
1797 } 1794 }
1798} 1795}
1799 1796
@@ -1808,8 +1805,7 @@ static void dw_mci_pull_data16(struct dw_mci *host, void *buf, int cnt)
1808 int items = len >> 1; 1805 int items = len >> 1;
1809 int i; 1806 int i;
1810 for (i = 0; i < items; ++i) 1807 for (i = 0; i < items; ++i)
1811 aligned_buf[i] = mci_readw(host, 1808 aligned_buf[i] = mci_fifo_readw(host->fifo_reg);
1812 DATA(host->data_offset));
1813 /* memcpy from aligned buffer into output buffer */ 1809 /* memcpy from aligned buffer into output buffer */
1814 memcpy(buf, aligned_buf, len); 1810 memcpy(buf, aligned_buf, len);
1815 buf += len; 1811 buf += len;
@@ -1820,11 +1816,11 @@ static void dw_mci_pull_data16(struct dw_mci *host, void *buf, int cnt)
1820 { 1816 {
1821 u16 *pdata = buf; 1817 u16 *pdata = buf;
1822 for (; cnt >= 2; cnt -= 2) 1818 for (; cnt >= 2; cnt -= 2)
1823 *pdata++ = mci_readw(host, DATA(host->data_offset)); 1819 *pdata++ = mci_fifo_readw(host->fifo_reg);
1824 buf = pdata; 1820 buf = pdata;
1825 } 1821 }
1826 if (cnt) { 1822 if (cnt) {
1827 host->part_buf16 = mci_readw(host, DATA(host->data_offset)); 1823 host->part_buf16 = mci_fifo_readw(host->fifo_reg);
1828 dw_mci_pull_final_bytes(host, buf, cnt); 1824 dw_mci_pull_final_bytes(host, buf, cnt);
1829 } 1825 }
1830} 1826}
@@ -1840,8 +1836,7 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt)
1840 buf += len; 1836 buf += len;
1841 cnt -= len; 1837 cnt -= len;
1842 if (host->part_buf_count == 4) { 1838 if (host->part_buf_count == 4) {
1843 mci_writel(host, DATA(host->data_offset), 1839 mci_fifo_writel(host->fifo_reg, host->part_buf32);
1844 host->part_buf32);
1845 host->part_buf_count = 0; 1840 host->part_buf_count = 0;
1846 } 1841 }
1847 } 1842 }
@@ -1858,15 +1853,14 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt)
1858 cnt -= len; 1853 cnt -= len;
1859 /* push data from aligned buffer into fifo */ 1854 /* push data from aligned buffer into fifo */
1860 for (i = 0; i < items; ++i) 1855 for (i = 0; i < items; ++i)
1861 mci_writel(host, DATA(host->data_offset), 1856 mci_fifo_writel(host->fifo_reg, aligned_buf[i]);
1862 aligned_buf[i]);
1863 } 1857 }
1864 } else 1858 } else
1865#endif 1859#endif
1866 { 1860 {
1867 u32 *pdata = buf; 1861 u32 *pdata = buf;
1868 for (; cnt >= 4; cnt -= 4) 1862 for (; cnt >= 4; cnt -= 4)
1869 mci_writel(host, DATA(host->data_offset), *pdata++); 1863 mci_fifo_writel(host->fifo_reg, *pdata++);
1870 buf = pdata; 1864 buf = pdata;
1871 } 1865 }
1872 /* put anything remaining in the part_buf */ 1866 /* put anything remaining in the part_buf */
@@ -1875,8 +1869,7 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt)
1875 /* Push data if we have reached the expected data length */ 1869 /* Push data if we have reached the expected data length */
1876 if ((data->bytes_xfered + init_cnt) == 1870 if ((data->bytes_xfered + init_cnt) ==
1877 (data->blksz * data->blocks)) 1871 (data->blksz * data->blocks))
1878 mci_writel(host, DATA(host->data_offset), 1872 mci_fifo_writel(host->fifo_reg, host->part_buf32);
1879 host->part_buf32);
1880 } 1873 }
1881} 1874}
1882 1875
@@ -1891,8 +1884,7 @@ static void dw_mci_pull_data32(struct dw_mci *host, void *buf, int cnt)
1891 int items = len >> 2; 1884 int items = len >> 2;
1892 int i; 1885 int i;
1893 for (i = 0; i < items; ++i) 1886 for (i = 0; i < items; ++i)
1894 aligned_buf[i] = mci_readl(host, 1887 aligned_buf[i] = mci_fifo_readl(host->fifo_reg);
1895 DATA(host->data_offset));
1896 /* memcpy from aligned buffer into output buffer */ 1888 /* memcpy from aligned buffer into output buffer */
1897 memcpy(buf, aligned_buf, len); 1889 memcpy(buf, aligned_buf, len);
1898 buf += len; 1890 buf += len;
@@ -1903,11 +1895,11 @@ static void dw_mci_pull_data32(struct dw_mci *host, void *buf, int cnt)
1903 { 1895 {
1904 u32 *pdata = buf; 1896 u32 *pdata = buf;
1905 for (; cnt >= 4; cnt -= 4) 1897 for (; cnt >= 4; cnt -= 4)
1906 *pdata++ = mci_readl(host, DATA(host->data_offset)); 1898 *pdata++ = mci_fifo_readl(host->fifo_reg);
1907 buf = pdata; 1899 buf = pdata;
1908 } 1900 }
1909 if (cnt) { 1901 if (cnt) {
1910 host->part_buf32 = mci_readl(host, DATA(host->data_offset)); 1902 host->part_buf32 = mci_fifo_readl(host->fifo_reg);
1911 dw_mci_pull_final_bytes(host, buf, cnt); 1903 dw_mci_pull_final_bytes(host, buf, cnt);
1912 } 1904 }
1913} 1905}
@@ -1924,8 +1916,7 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt)
1924 cnt -= len; 1916 cnt -= len;
1925 1917
1926 if (host->part_buf_count == 8) { 1918 if (host->part_buf_count == 8) {
1927 mci_writeq(host, DATA(host->data_offset), 1919 mci_fifo_writeq(host->fifo_reg, host->part_buf);
1928 host->part_buf);
1929 host->part_buf_count = 0; 1920 host->part_buf_count = 0;
1930 } 1921 }
1931 } 1922 }
@@ -1942,15 +1933,14 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt)
1942 cnt -= len; 1933 cnt -= len;
1943 /* push data from aligned buffer into fifo */ 1934 /* push data from aligned buffer into fifo */
1944 for (i = 0; i < items; ++i) 1935 for (i = 0; i < items; ++i)
1945 mci_writeq(host, DATA(host->data_offset), 1936 mci_fifo_writeq(host->fifo_reg, aligned_buf[i]);
1946 aligned_buf[i]);
1947 } 1937 }
1948 } else 1938 } else
1949#endif 1939#endif
1950 { 1940 {
1951 u64 *pdata = buf; 1941 u64 *pdata = buf;
1952 for (; cnt >= 8; cnt -= 8) 1942 for (; cnt >= 8; cnt -= 8)
1953 mci_writeq(host, DATA(host->data_offset), *pdata++); 1943 mci_fifo_writeq(host->fifo_reg, *pdata++);
1954 buf = pdata; 1944 buf = pdata;
1955 } 1945 }
1956 /* put anything remaining in the part_buf */ 1946 /* put anything remaining in the part_buf */
@@ -1959,8 +1949,7 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt)
1959 /* Push data if we have reached the expected data length */ 1949 /* Push data if we have reached the expected data length */
1960 if ((data->bytes_xfered + init_cnt) == 1950 if ((data->bytes_xfered + init_cnt) ==
1961 (data->blksz * data->blocks)) 1951 (data->blksz * data->blocks))
1962 mci_writeq(host, DATA(host->data_offset), 1952 mci_fifo_writeq(host->fifo_reg, host->part_buf);
1963 host->part_buf);
1964 } 1953 }
1965} 1954}
1966 1955
@@ -1975,8 +1964,8 @@ static void dw_mci_pull_data64(struct dw_mci *host, void *buf, int cnt)
1975 int items = len >> 3; 1964 int items = len >> 3;
1976 int i; 1965 int i;
1977 for (i = 0; i < items; ++i) 1966 for (i = 0; i < items; ++i)
1978 aligned_buf[i] = mci_readq(host, 1967 aligned_buf[i] = mci_fifo_readq(host->fifo_reg);
1979 DATA(host->data_offset)); 1968
1980 /* memcpy from aligned buffer into output buffer */ 1969 /* memcpy from aligned buffer into output buffer */
1981 memcpy(buf, aligned_buf, len); 1970 memcpy(buf, aligned_buf, len);
1982 buf += len; 1971 buf += len;
@@ -1987,11 +1976,11 @@ static void dw_mci_pull_data64(struct dw_mci *host, void *buf, int cnt)
1987 { 1976 {
1988 u64 *pdata = buf; 1977 u64 *pdata = buf;
1989 for (; cnt >= 8; cnt -= 8) 1978 for (; cnt >= 8; cnt -= 8)
1990 *pdata++ = mci_readq(host, DATA(host->data_offset)); 1979 *pdata++ = mci_fifo_readq(host->fifo_reg);
1991 buf = pdata; 1980 buf = pdata;
1992 } 1981 }
1993 if (cnt) { 1982 if (cnt) {
1994 host->part_buf = mci_readq(host, DATA(host->data_offset)); 1983 host->part_buf = mci_fifo_readq(host->fifo_reg);
1995 dw_mci_pull_final_bytes(host, buf, cnt); 1984 dw_mci_pull_final_bytes(host, buf, cnt);
1996 } 1985 }
1997} 1986}
@@ -2852,9 +2841,9 @@ int dw_mci_probe(struct dw_mci *host)
2852 dev_info(host->dev, "Version ID is %04x\n", host->verid); 2841 dev_info(host->dev, "Version ID is %04x\n", host->verid);
2853 2842
2854 if (host->verid < DW_MMC_240A) 2843 if (host->verid < DW_MMC_240A)
2855 host->data_offset = DATA_OFFSET; 2844 host->fifo_reg = host->regs + DATA_OFFSET;
2856 else 2845 else
2857 host->data_offset = DATA_240A_OFFSET; 2846 host->fifo_reg = host->regs + DATA_240A_OFFSET;
2858 2847
2859 tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host); 2848 tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host);
2860 ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt, 2849 ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt,
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index b8051d049fb7..f45ab91de339 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -169,6 +169,16 @@
169#define SDMMC_CTRL_ALL_RESET_FLAGS \ 169#define SDMMC_CTRL_ALL_RESET_FLAGS \
170 (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET) 170 (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET)
171 171
172/* FIFO register access macros. These should not change the data endian-ness
173 * as they are written to memory to be dealt with by the upper layers */
174#define mci_fifo_readw(__reg) __raw_readw(__reg)
175#define mci_fifo_readl(__reg) __raw_readl(__reg)
176#define mci_fifo_readq(__reg) __raw_readq(__reg)
177
178#define mci_fifo_writew(__value, __reg) __raw_writew(__reg, __value)
179#define mci_fifo_writel(__value, __reg) __raw_writel(__reg, __value)
180#define mci_fifo_writeq(__value, __reg) __raw_writeq(__reg, __value)
181
172/* Register access macros */ 182/* Register access macros */
173#define mci_readl(dev, reg) \ 183#define mci_readl(dev, reg) \
174 readl_relaxed((dev)->regs + SDMMC_##reg) 184 readl_relaxed((dev)->regs + SDMMC_##reg)
@@ -200,6 +210,10 @@
200 (*(volatile u64 __force *)((dev)->regs + SDMMC_##reg)) 210 (*(volatile u64 __force *)((dev)->regs + SDMMC_##reg))
201#define mci_writeq(dev, reg, value) \ 211#define mci_writeq(dev, reg, value) \
202 (*(volatile u64 __force *)((dev)->regs + SDMMC_##reg) = (value)) 212 (*(volatile u64 __force *)((dev)->regs + SDMMC_##reg) = (value))
213
214#define __raw_writeq(__value, __reg) \
215 (*(volatile u64 __force *)(__reg) = (__value))
216#define __raw_readq(__reg) (*(volatile u64 __force *)(__reg))
203#endif 217#endif
204 218
205extern int dw_mci_probe(struct dw_mci *host); 219extern int dw_mci_probe(struct dw_mci *host);
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 9efc567e3ced..12111993a317 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -44,6 +44,7 @@ struct mmc_data;
44 * struct dw_mci - MMC controller state shared between all slots 44 * struct dw_mci - MMC controller state shared between all slots
45 * @lock: Spinlock protecting the queue and associated data. 45 * @lock: Spinlock protecting the queue and associated data.
46 * @regs: Pointer to MMIO registers. 46 * @regs: Pointer to MMIO registers.
47 * @fifo_reg: Pointer to MMIO registers for data FIFO
47 * @sg: Scatterlist entry currently being processed by PIO code, if any. 48 * @sg: Scatterlist entry currently being processed by PIO code, if any.
48 * @sg_miter: PIO mapping scatterlist iterator. 49 * @sg_miter: PIO mapping scatterlist iterator.
49 * @cur_slot: The slot which is currently using the controller. 50 * @cur_slot: The slot which is currently using the controller.
@@ -79,7 +80,6 @@ struct mmc_data;
79 * @current_speed: Configured rate of the controller. 80 * @current_speed: Configured rate of the controller.
80 * @num_slots: Number of slots available. 81 * @num_slots: Number of slots available.
81 * @verid: Denote Version ID. 82 * @verid: Denote Version ID.
82 * @data_offset: Set the offset of DATA register according to VERID.
83 * @dev: Device associated with the MMC controller. 83 * @dev: Device associated with the MMC controller.
84 * @pdata: Platform data associated with the MMC controller. 84 * @pdata: Platform data associated with the MMC controller.
85 * @drv_data: Driver specific data for identified variant of the controller 85 * @drv_data: Driver specific data for identified variant of the controller
@@ -132,6 +132,7 @@ struct dw_mci {
132 spinlock_t lock; 132 spinlock_t lock;
133 spinlock_t irq_lock; 133 spinlock_t irq_lock;
134 void __iomem *regs; 134 void __iomem *regs;
135 void __iomem *fifo_reg;
135 136
136 struct scatterlist *sg; 137 struct scatterlist *sg;
137 struct sg_mapping_iter sg_miter; 138 struct sg_mapping_iter sg_miter;
@@ -172,7 +173,6 @@ struct dw_mci {
172 u32 num_slots; 173 u32 num_slots;
173 u32 fifoth_val; 174 u32 fifoth_val;
174 u16 verid; 175 u16 verid;
175 u16 data_offset;
176 struct device *dev; 176 struct device *dev;
177 struct dw_mci_board *pdata; 177 struct dw_mci_board *pdata;
178 const struct dw_mci_drv_data *drv_data; 178 const struct dw_mci_drv_data *drv_data;