diff options
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 59 | ||||
-rw-r--r-- | drivers/mmc/host/dw_mmc.h | 14 | ||||
-rw-r--r-- | include/linux/mmc/dw_mmc.h | 4 |
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 | ||
205 | extern int dw_mci_probe(struct dw_mci *host); | 219 | extern 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; |