kernel: bump to 4.4.39
[oweals/openwrt.git] / target / linux / layerscape / patches-4.4 / 1087-mtd-spi-nor-fsl-quadspi-add-big-endian-support.patch
1 From c58b398221d88ac0db29c3bb7522a4f48dfa102c Mon Sep 17 00:00:00 2001
2 From: Yuan Yao <yao.yuan@freescale.com>
3 Date: Tue, 17 Nov 2015 16:13:47 +0800
4 Subject: [PATCH 087/113] mtd: spi-nor: fsl-quadspi: add big-endian support
5
6 Add R/W functions for big- or little-endian registers:
7 The qSPI controller's endian is independent of the CPU core's endian.
8 So far, the qSPI have two versions for big-endian and little-endian.
9
10 Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
11 Acked-by: Han xu <han.xu@freescale.com>
12 ---
13  drivers/mtd/spi-nor/fsl-quadspi.c |  157 +++++++++++++++++++++++--------------
14  1 file changed, 97 insertions(+), 60 deletions(-)
15
16 --- a/drivers/mtd/spi-nor/fsl-quadspi.c
17 +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
18 @@ -275,6 +275,7 @@ struct fsl_qspi {
19         u32 clk_rate;
20         unsigned int chip_base_addr; /* We may support two chips. */
21         bool has_second_chip;
22 +       bool big_endian;
23         struct mutex lock;
24         struct pm_qos_request pm_qos_req;
25  };
26 @@ -300,6 +301,28 @@ static inline int needs_wakeup_wait_mode
27  }
28  
29  /*
30 + * R/W functions for big- or little-endian registers:
31 + * The qSPI controller's endian is independent of the CPU core's endian.
32 + * So far, although the CPU core is little-endian but the qSPI have two
33 + * versions for big-endian and little-endian.
34 + */
35 +static void qspi_writel(struct fsl_qspi *q, u32 val, void __iomem *addr)
36 +{
37 +       if (q->big_endian)
38 +               iowrite32be(val, addr);
39 +       else
40 +               iowrite32(val, addr);
41 +}
42 +
43 +static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr)
44 +{
45 +       if (q->big_endian)
46 +               return ioread32be(addr);
47 +       else
48 +               return ioread32(addr);
49 +}
50 +
51 +/*
52   * An IC bug makes us to re-arrange the 32-bit data.
53   * The following chips, such as IMX6SLX, have fixed this bug.
54   */
55 @@ -310,14 +333,14 @@ static inline u32 fsl_qspi_endian_xchg(s
56  
57  static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q)
58  {
59 -       writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
60 -       writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
61 +       qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
62 +       qspi_writel(q, QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
63  }
64  
65  static inline void fsl_qspi_lock_lut(struct fsl_qspi *q)
66  {
67 -       writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
68 -       writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
69 +       qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
70 +       qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
71  }
72  
73  static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
74 @@ -326,8 +349,8 @@ static irqreturn_t fsl_qspi_irq_handler(
75         u32 reg;
76  
77         /* clear interrupt */
78 -       reg = readl(q->iobase + QUADSPI_FR);
79 -       writel(reg, q->iobase + QUADSPI_FR);
80 +       reg = qspi_readl(q, q->iobase + QUADSPI_FR);
81 +       qspi_writel(q, reg, q->iobase + QUADSPI_FR);
82  
83         if (reg & QUADSPI_FR_TFF_MASK)
84                 complete(&q->c);
85 @@ -348,7 +371,7 @@ static void fsl_qspi_init_lut(struct fsl
86  
87         /* Clear all the LUT table */
88         for (i = 0; i < QUADSPI_LUT_NUM; i++)
89 -               writel(0, base + QUADSPI_LUT_BASE + i * 4);
90 +               qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
91  
92         /* Quad Read */
93         lut_base = SEQID_QUAD_READ * 4;
94 @@ -364,14 +387,15 @@ static void fsl_qspi_init_lut(struct fsl
95                 dummy = 8;
96         }
97  
98 -       writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
99 +       qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
100                         base + QUADSPI_LUT(lut_base));
101 -       writel(LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo),
102 +       qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo),
103                         base + QUADSPI_LUT(lut_base + 1));
104  
105         /* Write enable */
106         lut_base = SEQID_WREN * 4;
107 -       writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
108 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
109 +                       base + QUADSPI_LUT(lut_base));
110  
111         /* Page Program */
112         lut_base = SEQID_PP * 4;
113 @@ -385,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl
114                 addrlen = ADDR32BIT;
115         }
116  
117 -       writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
118 +       qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
119                         base + QUADSPI_LUT(lut_base));
120 -       writel(LUT0(FSL_WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
121 +       qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
122 +                       base + QUADSPI_LUT(lut_base + 1));
123  
124         /* Read Status */
125         lut_base = SEQID_RDSR * 4;
126 -       writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(FSL_READ, PAD1, 0x1),
127 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
128 +                       LUT1(FSL_READ, PAD1, 0x1),
129                         base + QUADSPI_LUT(lut_base));
130  
131         /* Erase a sector */
132 @@ -400,40 +426,46 @@ static void fsl_qspi_init_lut(struct fsl
133         cmd = q->nor[0].erase_opcode;
134         addrlen = q->nor_size <= SZ_16M ? ADDR24BIT : ADDR32BIT;
135  
136 -       writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
137 +       qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
138                         base + QUADSPI_LUT(lut_base));
139  
140         /* Erase the whole chip */
141         lut_base = SEQID_CHIP_ERASE * 4;
142 -       writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
143 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
144                         base + QUADSPI_LUT(lut_base));
145  
146         /* READ ID */
147         lut_base = SEQID_RDID * 4;
148 -       writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(FSL_READ, PAD1, 0x8),
149 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
150 +                       LUT1(FSL_READ, PAD1, 0x8),
151                         base + QUADSPI_LUT(lut_base));
152  
153         /* Write Register */
154         lut_base = SEQID_WRSR * 4;
155 -       writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(FSL_WRITE, PAD1, 0x2),
156 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
157 +                       LUT1(FSL_WRITE, PAD1, 0x2),
158                         base + QUADSPI_LUT(lut_base));
159  
160         /* Read Configuration Register */
161         lut_base = SEQID_RDCR * 4;
162 -       writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(FSL_READ, PAD1, 0x1),
163 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
164 +                       LUT1(FSL_READ, PAD1, 0x1),
165                         base + QUADSPI_LUT(lut_base));
166  
167         /* Write disable */
168         lut_base = SEQID_WRDI * 4;
169 -       writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base));
170 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
171 +                       base + QUADSPI_LUT(lut_base));
172  
173         /* Enter 4 Byte Mode (Micron) */
174         lut_base = SEQID_EN4B * 4;
175 -       writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base));
176 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
177 +                       base + QUADSPI_LUT(lut_base));
178  
179         /* Enter 4 Byte Mode (Spansion) */
180         lut_base = SEQID_BRWR * 4;
181 -       writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base));
182 +       qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
183 +                       base + QUADSPI_LUT(lut_base));
184  
185         fsl_qspi_lock_lut(q);
186  }
187 @@ -488,15 +520,16 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
188                         q->chip_base_addr, addr, len, cmd);
189  
190         /* save the reg */
191 -       reg = readl(base + QUADSPI_MCR);
192 +       reg = qspi_readl(q, base + QUADSPI_MCR);
193  
194 -       writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR);
195 -       writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
196 +       qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
197 +                       base + QUADSPI_SFAR);
198 +       qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
199                         base + QUADSPI_RBCT);
200 -       writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
201 +       qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
202  
203         do {
204 -               reg2 = readl(base + QUADSPI_SR);
205 +               reg2 = qspi_readl(q, base + QUADSPI_SR);
206                 if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) {
207                         udelay(1);
208                         dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2);
209 @@ -507,21 +540,22 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
210  
211         /* trigger the LUT now */
212         seqid = fsl_qspi_get_seqid(q, cmd);
213 -       writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR);
214 +       qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
215 +                       base + QUADSPI_IPCR);
216  
217         /* Wait for the interrupt. */
218         if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) {
219                 dev_err(q->dev,
220                         "cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n",
221 -                       cmd, addr, readl(base + QUADSPI_FR),
222 -                       readl(base + QUADSPI_SR));
223 +                       cmd, addr, qspi_readl(q, base + QUADSPI_FR),
224 +                       qspi_readl(q, base + QUADSPI_SR));
225                 err = -ETIMEDOUT;
226         } else {
227                 err = 0;
228         }
229  
230         /* restore the MCR */
231 -       writel(reg, base + QUADSPI_MCR);
232 +       qspi_writel(q, reg, base + QUADSPI_MCR);
233  
234         return err;
235  }
236 @@ -533,7 +567,7 @@ static void fsl_qspi_read_data(struct fs
237         int i = 0;
238  
239         while (len > 0) {
240 -               tmp = readl(q->iobase + QUADSPI_RBDR + i * 4);
241 +               tmp = qspi_readl(q, q->iobase + QUADSPI_RBDR + i * 4);
242                 tmp = fsl_qspi_endian_xchg(q, tmp);
243                 dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n",
244                                 q->chip_base_addr, tmp);
245 @@ -561,9 +595,9 @@ static inline void fsl_qspi_invalid(stru
246  {
247         u32 reg;
248  
249 -       reg = readl(q->iobase + QUADSPI_MCR);
250 +       reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
251         reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK;
252 -       writel(reg, q->iobase + QUADSPI_MCR);
253 +       qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
254  
255         /*
256          * The minimum delay : 1 AHB + 2 SFCK clocks.
257 @@ -572,7 +606,7 @@ static inline void fsl_qspi_invalid(stru
258         udelay(1);
259  
260         reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK);
261 -       writel(reg, q->iobase + QUADSPI_MCR);
262 +       qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
263  }
264  
265  static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
266 @@ -586,20 +620,20 @@ static int fsl_qspi_nor_write(struct fsl
267                 q->chip_base_addr, to, count);
268  
269         /* clear the TX FIFO. */
270 -       tmp = readl(q->iobase + QUADSPI_MCR);
271 -       writel(tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
272 +       tmp = qspi_readl(q, q->iobase + QUADSPI_MCR);
273 +       qspi_writel(q, tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
274  
275         /* fill the TX data to the FIFO */
276         for (j = 0, i = ((count + 3) / 4); j < i; j++) {
277                 tmp = fsl_qspi_endian_xchg(q, *txbuf);
278 -               writel(tmp, q->iobase + QUADSPI_TBDR);
279 +               qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
280                 txbuf++;
281         }
282  
283         /* fill the TXFIFO upto 16 bytes for i.MX7d */
284         if (needs_fill_txfifo(q))
285                 for (; i < 4; i++)
286 -                       writel(tmp, q->iobase + QUADSPI_TBDR);
287 +                       qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
288  
289         /* Trigger it */
290         ret = fsl_qspi_runcmd(q, opcode, to, count);
291 @@ -615,10 +649,10 @@ static void fsl_qspi_set_map_addr(struct
292         int nor_size = q->nor_size;
293         void __iomem *base = q->iobase;
294  
295 -       writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
296 -       writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
297 -       writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
298 -       writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
299 +       qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
300 +       qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
301 +       qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
302 +       qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
303  }
304  
305  /*
306 @@ -640,24 +674,26 @@ static void fsl_qspi_init_abh_read(struc
307         int seqid;
308  
309         /* AHB configuration for access buffer 0/1/2 .*/
310 -       writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
311 -       writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
312 -       writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
313 +       qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
314 +       qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
315 +       qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
316         /*
317          * Set ADATSZ with the maximum AHB buffer size to improve the
318          * read performance.
319          */
320 -       writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8)
321 -                       << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
322 +       qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
323 +                       ((q->devtype_data->ahb_buf_size / 8)
324 +                       << QUADSPI_BUF3CR_ADATSZ_SHIFT),
325 +                       base + QUADSPI_BUF3CR);
326  
327         /* We only use the buffer3 */
328 -       writel(0, base + QUADSPI_BUF0IND);
329 -       writel(0, base + QUADSPI_BUF1IND);
330 -       writel(0, base + QUADSPI_BUF2IND);
331 +       qspi_writel(q, 0, base + QUADSPI_BUF0IND);
332 +       qspi_writel(q, 0, base + QUADSPI_BUF1IND);
333 +       qspi_writel(q, 0, base + QUADSPI_BUF2IND);
334  
335         /* Set the default lut sequence for AHB Read. */
336         seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
337 -       writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
338 +       qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
339                 q->iobase + QUADSPI_BFGENCR);
340  }
341  
342 @@ -713,7 +749,7 @@ static int fsl_qspi_nor_setup(struct fsl
343                 return ret;
344  
345         /* Reset the module */
346 -       writel(QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
347 +       qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
348                 base + QUADSPI_MCR);
349         udelay(1);
350  
351 @@ -721,24 +757,24 @@ static int fsl_qspi_nor_setup(struct fsl
352         fsl_qspi_init_lut(q);
353  
354         /* Disable the module */
355 -       writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
356 +       qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
357                         base + QUADSPI_MCR);
358  
359 -       reg = readl(base + QUADSPI_SMPR);
360 -       writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK
361 +       reg = qspi_readl(q, base + QUADSPI_SMPR);
362 +       qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK
363                         | QUADSPI_SMPR_FSPHS_MASK
364                         | QUADSPI_SMPR_HSENA_MASK
365                         | QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
366  
367         /* Enable the module */
368 -       writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
369 +       qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
370                         base + QUADSPI_MCR);
371  
372         /* clear all interrupt status */
373 -       writel(0xffffffff, q->iobase + QUADSPI_FR);
374 +       qspi_writel(q, 0xffffffff, q->iobase + QUADSPI_FR);
375  
376         /* enable the interrupt */
377 -       writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
378 +       qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
379  
380         return 0;
381  }
382 @@ -954,6 +990,7 @@ static int fsl_qspi_probe(struct platfor
383         if (IS_ERR(q->iobase))
384                 return PTR_ERR(q->iobase);
385  
386 +       q->big_endian = of_property_read_bool(np, "big-endian");
387         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
388                                         "QuadSPI-memory");
389         if (!devm_request_mem_region(dev, res->start, resource_size(res),
390 @@ -1101,8 +1138,8 @@ static int fsl_qspi_remove(struct platfo
391         }
392  
393         /* disable the hardware */
394 -       writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
395 -       writel(0x0, q->iobase + QUADSPI_RSER);
396 +       qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
397 +       qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
398  
399         mutex_destroy(&q->lock);
400