diff options
| -rw-r--r-- | drivers/spi/spi-ti-qspi.c | 139 |
1 files changed, 110 insertions, 29 deletions
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 64318fcfacf2..eac3c960b2de 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c | |||
| @@ -31,6 +31,8 @@ | |||
| 31 | #include <linux/of.h> | 31 | #include <linux/of.h> |
| 32 | #include <linux/of_device.h> | 32 | #include <linux/of_device.h> |
| 33 | #include <linux/pinctrl/consumer.h> | 33 | #include <linux/pinctrl/consumer.h> |
| 34 | #include <linux/mfd/syscon.h> | ||
| 35 | #include <linux/regmap.h> | ||
| 34 | 36 | ||
| 35 | #include <linux/spi/spi.h> | 37 | #include <linux/spi/spi.h> |
| 36 | 38 | ||
| @@ -44,8 +46,9 @@ struct ti_qspi { | |||
| 44 | 46 | ||
| 45 | struct spi_master *master; | 47 | struct spi_master *master; |
| 46 | void __iomem *base; | 48 | void __iomem *base; |
| 47 | void __iomem *ctrl_base; | ||
| 48 | void __iomem *mmap_base; | 49 | void __iomem *mmap_base; |
| 50 | struct regmap *ctrl_base; | ||
| 51 | unsigned int ctrl_reg; | ||
| 49 | struct clk *fclk; | 52 | struct clk *fclk; |
| 50 | struct device *dev; | 53 | struct device *dev; |
| 51 | 54 | ||
| @@ -55,7 +58,7 @@ struct ti_qspi { | |||
| 55 | u32 cmd; | 58 | u32 cmd; |
| 56 | u32 dc; | 59 | u32 dc; |
| 57 | 60 | ||
| 58 | bool ctrl_mod; | 61 | bool mmap_enabled; |
| 59 | }; | 62 | }; |
| 60 | 63 | ||
| 61 | #define QSPI_PID (0x0) | 64 | #define QSPI_PID (0x0) |
| @@ -65,11 +68,8 @@ struct ti_qspi { | |||
| 65 | #define QSPI_SPI_CMD_REG (0x48) | 68 | #define QSPI_SPI_CMD_REG (0x48) |
| 66 | #define QSPI_SPI_STATUS_REG (0x4c) | 69 | #define QSPI_SPI_STATUS_REG (0x4c) |
| 67 | #define QSPI_SPI_DATA_REG (0x50) | 70 | #define QSPI_SPI_DATA_REG (0x50) |
| 68 | #define QSPI_SPI_SETUP0_REG (0x54) | 71 | #define QSPI_SPI_SETUP_REG(n) ((0x54 + 4 * n)) |
| 69 | #define QSPI_SPI_SWITCH_REG (0x64) | 72 | #define QSPI_SPI_SWITCH_REG (0x64) |
| 70 | #define QSPI_SPI_SETUP1_REG (0x58) | ||
| 71 | #define QSPI_SPI_SETUP2_REG (0x5c) | ||
| 72 | #define QSPI_SPI_SETUP3_REG (0x60) | ||
| 73 | #define QSPI_SPI_DATA_REG_1 (0x68) | 73 | #define QSPI_SPI_DATA_REG_1 (0x68) |
| 74 | #define QSPI_SPI_DATA_REG_2 (0x6c) | 74 | #define QSPI_SPI_DATA_REG_2 (0x6c) |
| 75 | #define QSPI_SPI_DATA_REG_3 (0x70) | 75 | #define QSPI_SPI_DATA_REG_3 (0x70) |
| @@ -109,6 +109,17 @@ struct ti_qspi { | |||
| 109 | 109 | ||
| 110 | #define QSPI_AUTOSUSPEND_TIMEOUT 2000 | 110 | #define QSPI_AUTOSUSPEND_TIMEOUT 2000 |
| 111 | 111 | ||
| 112 | #define MEM_CS_EN(n) ((n + 1) << 8) | ||
| 113 | #define MEM_CS_MASK (7 << 8) | ||
| 114 | |||
| 115 | #define MM_SWITCH 0x1 | ||
| 116 | |||
| 117 | #define QSPI_SETUP_RD_NORMAL (0x0 << 12) | ||
| 118 | #define QSPI_SETUP_RD_DUAL (0x1 << 12) | ||
| 119 | #define QSPI_SETUP_RD_QUAD (0x3 << 12) | ||
| 120 | #define QSPI_SETUP_ADDR_SHIFT 8 | ||
| 121 | #define QSPI_SETUP_DUMMY_SHIFT 10 | ||
| 122 | |||
| 112 | static inline unsigned long ti_qspi_read(struct ti_qspi *qspi, | 123 | static inline unsigned long ti_qspi_read(struct ti_qspi *qspi, |
| 113 | unsigned long reg) | 124 | unsigned long reg) |
| 114 | { | 125 | { |
| @@ -366,6 +377,72 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) | |||
| 366 | return 0; | 377 | return 0; |
| 367 | } | 378 | } |
| 368 | 379 | ||
| 380 | static void ti_qspi_enable_memory_map(struct spi_device *spi) | ||
| 381 | { | ||
| 382 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | ||
| 383 | |||
| 384 | ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG); | ||
| 385 | if (qspi->ctrl_base) { | ||
| 386 | regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg, | ||
| 387 | MEM_CS_EN(spi->chip_select), | ||
| 388 | MEM_CS_MASK); | ||
| 389 | } | ||
| 390 | qspi->mmap_enabled = true; | ||
| 391 | } | ||
| 392 | |||
| 393 | static void ti_qspi_disable_memory_map(struct spi_device *spi) | ||
| 394 | { | ||
| 395 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | ||
| 396 | |||
| 397 | ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG); | ||
| 398 | if (qspi->ctrl_base) | ||
| 399 | regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg, | ||
| 400 | 0, MEM_CS_MASK); | ||
| 401 | qspi->mmap_enabled = false; | ||
| 402 | } | ||
| 403 | |||
| 404 | static void ti_qspi_setup_mmap_read(struct spi_device *spi, | ||
| 405 | struct spi_flash_read_message *msg) | ||
| 406 | { | ||
| 407 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | ||
| 408 | u32 memval = msg->read_opcode; | ||
| 409 | |||
| 410 | switch (msg->data_nbits) { | ||
| 411 | case SPI_NBITS_QUAD: | ||
| 412 | memval |= QSPI_SETUP_RD_QUAD; | ||
| 413 | break; | ||
| 414 | case SPI_NBITS_DUAL: | ||
| 415 | memval |= QSPI_SETUP_RD_DUAL; | ||
| 416 | break; | ||
| 417 | default: | ||
| 418 | memval |= QSPI_SETUP_RD_NORMAL; | ||
| 419 | break; | ||
| 420 | } | ||
| 421 | memval |= ((msg->addr_width - 1) << QSPI_SETUP_ADDR_SHIFT | | ||
| 422 | msg->dummy_bytes << QSPI_SETUP_DUMMY_SHIFT); | ||
| 423 | ti_qspi_write(qspi, memval, | ||
| 424 | QSPI_SPI_SETUP_REG(spi->chip_select)); | ||
| 425 | } | ||
| 426 | |||
| 427 | static int ti_qspi_spi_flash_read(struct spi_device *spi, | ||
| 428 | struct spi_flash_read_message *msg) | ||
| 429 | { | ||
| 430 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | ||
| 431 | int ret = 0; | ||
| 432 | |||
| 433 | mutex_lock(&qspi->list_lock); | ||
| 434 | |||
| 435 | if (!qspi->mmap_enabled) | ||
| 436 | ti_qspi_enable_memory_map(spi); | ||
| 437 | ti_qspi_setup_mmap_read(spi, msg); | ||
| 438 | memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len); | ||
| 439 | msg->retlen = msg->len; | ||
| 440 | |||
| 441 | mutex_unlock(&qspi->list_lock); | ||
| 442 | |||
| 443 | return ret; | ||
| 444 | } | ||
| 445 | |||
| 369 | static int ti_qspi_start_transfer_one(struct spi_master *master, | 446 | static int ti_qspi_start_transfer_one(struct spi_master *master, |
| 370 | struct spi_message *m) | 447 | struct spi_message *m) |
| 371 | { | 448 | { |
| @@ -398,6 +475,9 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, | |||
| 398 | 475 | ||
| 399 | mutex_lock(&qspi->list_lock); | 476 | mutex_lock(&qspi->list_lock); |
| 400 | 477 | ||
| 478 | if (qspi->mmap_enabled) | ||
| 479 | ti_qspi_disable_memory_map(spi); | ||
| 480 | |||
| 401 | list_for_each_entry(t, &m->transfers, transfer_list) { | 481 | list_for_each_entry(t, &m->transfers, transfer_list) { |
| 402 | qspi->cmd |= QSPI_WLEN(t->bits_per_word); | 482 | qspi->cmd |= QSPI_WLEN(t->bits_per_word); |
| 403 | 483 | ||
| @@ -441,7 +521,7 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 441 | { | 521 | { |
| 442 | struct ti_qspi *qspi; | 522 | struct ti_qspi *qspi; |
| 443 | struct spi_master *master; | 523 | struct spi_master *master; |
| 444 | struct resource *r, *res_ctrl, *res_mmap; | 524 | struct resource *r, *res_mmap; |
| 445 | struct device_node *np = pdev->dev.of_node; | 525 | struct device_node *np = pdev->dev.of_node; |
| 446 | u32 max_freq; | 526 | u32 max_freq; |
| 447 | int ret = 0, num_cs, irq; | 527 | int ret = 0, num_cs, irq; |
| @@ -487,16 +567,6 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 487 | } | 567 | } |
| 488 | } | 568 | } |
| 489 | 569 | ||
| 490 | res_ctrl = platform_get_resource_byname(pdev, | ||
| 491 | IORESOURCE_MEM, "qspi_ctrlmod"); | ||
| 492 | if (res_ctrl == NULL) { | ||
| 493 | res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
| 494 | if (res_ctrl == NULL) { | ||
| 495 | dev_dbg(&pdev->dev, | ||
| 496 | "control module resources not required\n"); | ||
| 497 | } | ||
| 498 | } | ||
| 499 | |||
| 500 | irq = platform_get_irq(pdev, 0); | 570 | irq = platform_get_irq(pdev, 0); |
| 501 | if (irq < 0) { | 571 | if (irq < 0) { |
| 502 | dev_err(&pdev->dev, "no irq resource?\n"); | 572 | dev_err(&pdev->dev, "no irq resource?\n"); |
| @@ -511,20 +581,31 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 511 | goto free_master; | 581 | goto free_master; |
| 512 | } | 582 | } |
| 513 | 583 | ||
| 514 | if (res_ctrl) { | ||
| 515 | qspi->ctrl_mod = true; | ||
| 516 | qspi->ctrl_base = devm_ioremap_resource(&pdev->dev, res_ctrl); | ||
| 517 | if (IS_ERR(qspi->ctrl_base)) { | ||
| 518 | ret = PTR_ERR(qspi->ctrl_base); | ||
| 519 | goto free_master; | ||
| 520 | } | ||
| 521 | } | ||
| 522 | |||
| 523 | if (res_mmap) { | 584 | if (res_mmap) { |
| 524 | qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap); | 585 | qspi->mmap_base = devm_ioremap_resource(&pdev->dev, |
| 586 | res_mmap); | ||
| 587 | master->spi_flash_read = ti_qspi_spi_flash_read; | ||
| 525 | if (IS_ERR(qspi->mmap_base)) { | 588 | if (IS_ERR(qspi->mmap_base)) { |
| 526 | ret = PTR_ERR(qspi->mmap_base); | 589 | dev_err(&pdev->dev, |
| 527 | |||
