Commit 52e2565bfb5d332e53021c6ec437cdb95eaf9dde

Authored by Tudor Ambarus
Committed by Jagan Teki
1 parent ba03a6c944

spi: atmel-quadspi: Add verbose debug facilities to monitor register accesses

This feature should not be enabled in release but can be useful for
developers who need to monitor register accesses at some specific places.

Helped me identify a bug in u-boot, by comparing the register accesses
from the u-boot driver with the ones from its linux variant.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
[jagan: use 16 bit array with tmp variable]
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>

Showing 1 changed file with 96 additions and 18 deletions Side-by-side Diff

drivers/spi/atmel-quadspi.c
... ... @@ -148,6 +148,7 @@
148 148 void __iomem *mem;
149 149 resource_size_t mmap_size;
150 150 const struct atmel_qspi_caps *caps;
  151 + struct udevice *dev;
151 152 ulong bus_clk_rate;
152 153 u32 mr;
153 154 };
... ... @@ -169,6 +170,81 @@
169 170 { 4, 4, 4, QSPI_IFR_WIDTH_QUAD_CMD },
170 171 };
171 172  
  173 +#ifdef VERBOSE_DEBUG
  174 +static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz)
  175 +{
  176 + switch (offset) {
  177 + case QSPI_CR:
  178 + return "CR";
  179 + case QSPI_MR:
  180 + return "MR";
  181 + case QSPI_RD:
  182 + return "MR";
  183 + case QSPI_TD:
  184 + return "TD";
  185 + case QSPI_SR:
  186 + return "SR";
  187 + case QSPI_IER:
  188 + return "IER";
  189 + case QSPI_IDR:
  190 + return "IDR";
  191 + case QSPI_IMR:
  192 + return "IMR";
  193 + case QSPI_SCR:
  194 + return "SCR";
  195 + case QSPI_IAR:
  196 + return "IAR";
  197 + case QSPI_ICR:
  198 + return "ICR/WICR";
  199 + case QSPI_IFR:
  200 + return "IFR";
  201 + case QSPI_RICR:
  202 + return "RICR";
  203 + case QSPI_SMR:
  204 + return "SMR";
  205 + case QSPI_SKR:
  206 + return "SKR";
  207 + case QSPI_WPMR:
  208 + return "WPMR";
  209 + case QSPI_WPSR:
  210 + return "WPSR";
  211 + case QSPI_VERSION:
  212 + return "VERSION";
  213 + default:
  214 + snprintf(tmp, sz, "0x%02x", offset);
  215 + break;
  216 + }
  217 +
  218 + return tmp;
  219 +}
  220 +#endif /* VERBOSE_DEBUG */
  221 +
  222 +static u32 atmel_qspi_read(struct atmel_qspi *aq, u32 offset)
  223 +{
  224 + u32 value = readl(aq->regs + offset);
  225 +
  226 +#ifdef VERBOSE_DEBUG
  227 + char tmp[16];
  228 +
  229 + dev_vdbg(aq->dev, "read 0x%08x from %s\n", value,
  230 + atmel_qspi_reg_name(offset, tmp, sizeof(tmp)));
  231 +#endif /* VERBOSE_DEBUG */
  232 +
  233 + return value;
  234 +}
  235 +
  236 +static void atmel_qspi_write(u32 value, struct atmel_qspi *aq, u32 offset)
  237 +{
  238 +#ifdef VERBOSE_DEBUG
  239 + char tmp[16];
  240 +
  241 + dev_vdbg(aq->dev, "write 0x%08x into %s\n", value,
  242 + atmel_qspi_reg_name(offset, tmp, sizeof(tmp)));
  243 +#endif /* VERBOSE_DEBUG */
  244 +
  245 + writel(value, aq->regs + offset);
  246 +}
  247 +
172 248 static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op,
173 249 const struct atmel_qspi_mode *mode)
174 250 {
175 251  
176 252  
177 253  
178 254  
179 255  
... ... @@ -289,32 +365,32 @@
289 365 * Serial Memory Mode (SMM).
290 366 */
291 367 if (aq->mr != QSPI_MR_SMM) {
292   - writel(QSPI_MR_SMM, aq->regs + QSPI_MR);
  368 + atmel_qspi_write(QSPI_MR_SMM, aq, QSPI_MR);
293 369 aq->mr = QSPI_MR_SMM;
294 370 }
295 371  
296 372 /* Clear pending interrupts */
297   - (void)readl(aq->regs + QSPI_SR);
  373 + (void)atmel_qspi_read(aq, QSPI_SR);
298 374  
299 375 if (aq->caps->has_ricr) {
300 376 if (!op->addr.nbytes && op->data.dir == SPI_MEM_DATA_IN)
301 377 ifr |= QSPI_IFR_APBTFRTYP_READ;
302 378  
303 379 /* Set QSPI Instruction Frame registers */
304   - writel(iar, aq->regs + QSPI_IAR);
  380 + atmel_qspi_write(iar, aq, QSPI_IAR);
305 381 if (op->data.dir == SPI_MEM_DATA_IN)
306   - writel(icr, aq->regs + QSPI_RICR);
  382 + atmel_qspi_write(icr, aq, QSPI_RICR);
307 383 else
308   - writel(icr, aq->regs + QSPI_WICR);
309   - writel(ifr, aq->regs + QSPI_IFR);
  384 + atmel_qspi_write(icr, aq, QSPI_WICR);
  385 + atmel_qspi_write(ifr, aq, QSPI_IFR);
310 386 } else {
311 387 if (op->data.dir == SPI_MEM_DATA_OUT)
312 388 ifr |= QSPI_IFR_SAMA5D2_WRITE_TRSFR;
313 389  
314 390 /* Set QSPI Instruction Frame registers */
315   - writel(iar, aq->regs + QSPI_IAR);
316   - writel(icr, aq->regs + QSPI_ICR);
317   - writel(ifr, aq->regs + QSPI_IFR);
  391 + atmel_qspi_write(iar, aq, QSPI_IAR);
  392 + atmel_qspi_write(icr, aq, QSPI_ICR);
  393 + atmel_qspi_write(ifr, aq, QSPI_IFR);
318 394 }
319 395  
320 396 return 0;
... ... @@ -342,7 +418,7 @@
342 418 /* Skip to the final steps if there is no data */
343 419 if (op->data.nbytes) {
344 420 /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
345   - (void)readl(aq->regs + QSPI_IFR);
  421 + (void)atmel_qspi_read(aq, QSPI_IFR);
346 422  
347 423 /* Send/Receive data */
348 424 if (op->data.dir == SPI_MEM_DATA_IN)
... ... @@ -353,7 +429,7 @@
353 429 op->data.nbytes);
354 430  
355 431 /* Release the chip-select */
356   - writel(QSPI_CR_LASTXFER, aq->regs + QSPI_CR);
  432 + atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
357 433 }
358 434  
359 435 /* Poll INSTruction End and Chip Select Rise flags. */
360 436  
... ... @@ -375,12 +451,12 @@
375 451 new_value = QSPI_SCR_SCBR(scbr);
376 452 mask = QSPI_SCR_SCBR_MASK;
377 453  
378   - scr = readl(aq->regs + QSPI_SCR);
  454 + scr = atmel_qspi_read(aq, QSPI_SCR);
379 455 if ((scr & mask) == new_value)
380 456 return 0;
381 457  
382 458 scr = (scr & ~mask) | new_value;
383   - writel(scr, aq->regs + QSPI_SCR);
  459 + atmel_qspi_write(scr, aq, QSPI_SCR);
384 460  
385 461 return 0;
386 462 }
387 463  
... ... @@ -397,12 +473,12 @@
397 473  
398 474 mask = QSPI_SCR_CPOL | QSPI_SCR_CPHA;
399 475  
400   - scr = readl(aq->regs + QSPI_SCR);
  476 + scr = atmel_qspi_read(aq, QSPI_SCR);
401 477 if ((scr & mask) == new_value)
402 478 return 0;
403 479  
404 480 scr = (scr & ~mask) | new_value;
405   - writel(scr, aq->regs + QSPI_SCR);
  481 + atmel_qspi_write(scr, aq, QSPI_SCR);
406 482  
407 483 return 0;
408 484 }
409 485  
410 486  
... ... @@ -455,14 +531,14 @@
455 531 static void atmel_qspi_init(struct atmel_qspi *aq)
456 532 {
457 533 /* Reset the QSPI controller */
458   - writel(QSPI_CR_SWRST, aq->regs + QSPI_CR);
  534 + atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR);
459 535  
460 536 /* Set the QSPI controller by default in Serial Memory Mode */
461   - writel(QSPI_MR_SMM, aq->regs + QSPI_MR);
  537 + atmel_qspi_write(QSPI_MR_SMM, aq, QSPI_MR);
462 538 aq->mr = QSPI_MR_SMM;
463 539  
464 540 /* Enable the QSPI controller */
465   - writel(QSPI_CR_QSPIEN, aq->regs + QSPI_CR);
  541 + atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
466 542 }
467 543  
468 544 static int atmel_qspi_probe(struct udevice *dev)
... ... @@ -504,6 +580,8 @@
504 580 ret = atmel_qspi_enable_clk(dev);
505 581 if (ret)
506 582 return ret;
  583 +
  584 + aq->dev = dev;
507 585  
508 586 atmel_qspi_init(aq);
509 587