Root/target/linux/ar71xx/patches-3.3/463-spi-ath79-add-fast-flash-read.patch

1--- a/drivers/spi/spi-ath79.c
2+++ b/drivers/spi/spi-ath79.c
3@@ -37,6 +37,11 @@
4 
5 #define ATH79_SPI_CS_LINE_MAX 2
6 
7+enum ath79_spi_state {
8+ ATH79_SPI_STATE_WAIT_CMD = 0,
9+ ATH79_SPI_STATE_WAIT_READ,
10+};
11+
12 struct ath79_spi {
13     struct spi_bitbang bitbang;
14     u32 ioc_base;
15@@ -44,6 +49,11 @@ struct ath79_spi {
16     void __iomem *base;
17     struct clk *clk;
18     unsigned rrw_delay;
19+
20+ enum ath79_spi_state state;
21+ u32 clk_div;
22+ unsigned long read_addr;
23+ unsigned long ahb_rate;
24 };
25 
26 static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
27@@ -111,9 +121,6 @@ static void ath79_spi_enable(struct ath7
28     /* save CTRL register */
29     sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL);
30     sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC);
31-
32- /* TODO: setup speed? */
33- ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
34 }
35 
36 static void ath79_spi_disable(struct ath79_spi *sp)
37@@ -232,6 +239,110 @@ static u32 ath79_spi_txrx_mode0(struct s
38     return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
39 }
40 
41+static int ath79_spi_do_read_flash_data(struct spi_device *spi,
42+ struct spi_transfer *t)
43+{
44+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
45+
46+ /* disable GPIO mode */
47+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
48+
49+ memcpy_fromio(t->rx_buf, sp->base + sp->read_addr, t->len);
50+
51+ /* enable GPIO mode */
52+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
53+
54+ /* restore IOC register */
55+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
56+
57+ return t->len;
58+}
59+
60+static int ath79_spi_do_read_flash_cmd(struct spi_device *spi,
61+ struct spi_transfer *t)
62+{
63+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
64+ int len;
65+ const u8 *p;
66+
67+ sp->read_addr = 0;
68+
69+ len = t->len - 1;
70+ p = t->tx_buf;
71+
72+ while (len--) {
73+ p++;
74+ sp->read_addr <<= 8;
75+ sp->read_addr |= *p;
76+ }
77+
78+ return t->len;
79+}
80+
81+static bool ath79_spi_is_read_cmd(struct spi_device *spi,
82+ struct spi_transfer *t)
83+{
84+ return t->type == SPI_TRANSFER_FLASH_READ_CMD;
85+}
86+
87+static bool ath79_spi_is_data_read(struct spi_device *spi,
88+ struct spi_transfer *t)
89+{
90+ return t->type == SPI_TRANSFER_FLASH_READ_DATA;
91+}
92+
93+static int ath79_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
94+{
95+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
96+ int ret;
97+
98+ switch (sp->state) {
99+ case ATH79_SPI_STATE_WAIT_CMD:
100+ if (ath79_spi_is_read_cmd(spi, t)) {
101+ ret = ath79_spi_do_read_flash_cmd(spi, t);
102+ sp->state = ATH79_SPI_STATE_WAIT_READ;
103+ } else {
104+ ret = spi_bitbang_bufs(spi, t);
105+ }
106+ break;
107+
108+ case ATH79_SPI_STATE_WAIT_READ:
109+ if (ath79_spi_is_data_read(spi, t)) {
110+ ret = ath79_spi_do_read_flash_data(spi, t);
111+ } else {
112+ dev_warn(&spi->dev, "flash data read expected\n");
113+ ret = -EIO;
114+ }
115+ sp->state = ATH79_SPI_STATE_WAIT_CMD;
116+ break;
117+
118+ default:
119+ BUG();
120+ }
121+
122+ return ret;
123+}
124+
125+static int ath79_spi_setup_transfer(struct spi_device *spi,
126+ struct spi_transfer *t)
127+{
128+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
129+ struct ath79_spi_controller_data *cdata;
130+ int ret;
131+
132+ ret = spi_bitbang_setup_transfer(spi, t);
133+ if (ret)
134+ return ret;
135+
136+ cdata = spi->controller_data;
137+ if (cdata->is_flash)
138+ sp->bitbang.txrx_bufs = ath79_spi_txrx_bufs;
139+ else
140+ sp->bitbang.txrx_bufs = spi_bitbang_bufs;
141+
142+ return ret;
143+}
144+
145 static __devinit int ath79_spi_probe(struct platform_device *pdev)
146 {
147     struct spi_master *master;
148@@ -254,6 +365,8 @@ static __devinit int ath79_spi_probe(str
149     sp = spi_master_get_devdata(master);
150     platform_set_drvdata(pdev, sp);
151 
152+ sp->state = ATH79_SPI_STATE_WAIT_CMD;
153+
154     master->setup = ath79_spi_setup;
155     master->cleanup = ath79_spi_cleanup;
156     master->bus_num = pdata->bus_num;
157@@ -262,7 +375,7 @@ static __devinit int ath79_spi_probe(str
158     sp->bitbang.master = spi_master_get(master);
159     sp->bitbang.chipselect = ath79_spi_chipselect;
160     sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
161- sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
162+ sp->bitbang.setup_transfer = ath79_spi_setup_transfer;
163     sp->bitbang.flags = SPI_CS_HIGH;
164 
165     r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
166@@ -287,7 +400,8 @@ static __devinit int ath79_spi_probe(str
167     if (ret)
168         goto err_clk_put;
169 
170- rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);
171+ sp->ahb_rate = clk_get_rate(sp->clk);
172+ rate = DIV_ROUND_UP(sp->ahb_rate, MHZ);
173     if (!rate) {
174         ret = -EINVAL;
175         goto err_clk_disable;
176--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
177+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
178@@ -24,6 +24,7 @@ enum ath79_spi_cs_type {
179 struct ath79_spi_controller_data {
180     enum ath79_spi_cs_type cs_type;
181     unsigned cs_line;
182+ bool is_flash;
183 };
184 
185 #endif /* _ATH79_SPI_PLATFORM_H */
186

Archive Download this file



interactive