diff options
| -rw-r--r-- | drivers/spi/spi-bcm-qspi.c | 89 |
1 files changed, 33 insertions, 56 deletions
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index b19722ba908c..6ef6c44f39f5 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
| 26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/mtd/spi-nor.h> | ||
| 29 | #include <linux/of.h> | 28 | #include <linux/of.h> |
| 30 | #include <linux/of_irq.h> | 29 | #include <linux/of_irq.h> |
| 31 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
| @@ -349,76 +348,60 @@ static void bcm_qspi_bspi_set_xfer_params(struct bcm_qspi *qspi, u8 cmd_byte, | |||
| 349 | bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, flex_mode); | 348 | bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, flex_mode); |
| 350 | } | 349 | } |
| 351 | 350 | ||
| 352 | static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi, int width, | 351 | static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi, |
| 353 | int addrlen, int hp) | 352 | struct spi_flash_read_message *msg, |
| 353 | int hp) | ||
| 354 | { | 354 | { |
| 355 | int bpc = 0, bpp = 0; | 355 | int bpc = 0, bpp = 0; |
| 356 | u8 command = SPINOR_OP_READ_FAST; | 356 | u8 command = msg->read_opcode; |
| 357 | int flex_mode = 1, rv = 0; | 357 | int width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE; |
| 358 | bool spans_4byte = false; | 358 | int addrlen = msg->addr_width; |
| 359 | int addr_nbits = msg->addr_nbits ? msg->addr_nbits : SPI_NBITS_SINGLE; | ||
| 360 | int flex_mode = 1; | ||
| 359 | 361 | ||
| 360 | dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n", | 362 | dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n", |
| 361 | width, addrlen, hp); | 363 | width, addrlen, hp); |
| 362 | 364 | ||
| 363 | if (addrlen == BSPI_ADDRLEN_4BYTES) { | 365 | if (addrlen == BSPI_ADDRLEN_4BYTES) |
| 364 | bpp = BSPI_BPP_ADDR_SELECT_MASK; | 366 | bpp = BSPI_BPP_ADDR_SELECT_MASK; |
| 365 | spans_4byte = true; | ||
| 366 | } | ||
| 367 | 367 | ||
| 368 | bpp |= 8; | 368 | bpp |= msg->dummy_bytes * (8/addr_nbits); |
| 369 | 369 | ||
| 370 | switch (width) { | 370 | switch (width) { |
| 371 | case SPI_NBITS_SINGLE: | 371 | case SPI_NBITS_SINGLE: |
| 372 | if (addrlen == BSPI_ADDRLEN_3BYTES) | 372 | if (addrlen == BSPI_ADDRLEN_3BYTES) |
| 373 | /* default mode, does not need flex_cmd */ | 373 | /* default mode, does not need flex_cmd */ |
| 374 | flex_mode = 0; | 374 | flex_mode = 0; |
| 375 | else | ||
| 376 | command = SPINOR_OP_READ_FAST_4B; | ||
| 377 | break; | 375 | break; |
| 378 | case SPI_NBITS_DUAL: | 376 | case SPI_NBITS_DUAL: |
| 379 | bpc = 0x00000001; | 377 | bpc = 0x00000001; |
| 380 | if (hp) { | 378 | if (hp) { |
| 381 | bpc |= 0x00010100; /* address and mode are 2-bit */ | 379 | bpc |= 0x00010100; /* address and mode are 2-bit */ |
| 382 | bpp = BSPI_BPP_MODE_SELECT_MASK; | 380 | bpp = BSPI_BPP_MODE_SELECT_MASK; |
| 383 | command = OPCODE_DIOR; | ||
| 384 | if (spans_4byte) | ||
| 385 | command = OPCODE_DIOR_4B; | ||
| 386 | } else { | ||
| 387 | command = SPINOR_OP_READ_1_1_2; | ||
| 388 | if (spans_4byte) | ||
| 389 | command = SPINOR_OP_READ_1_1_2_4B; | ||
| 390 | } | 381 | } |
| 391 | break; | 382 | break; |
| 392 | case SPI_NBITS_QUAD: | 383 | case SPI_NBITS_QUAD: |
| 393 | bpc = 0x00000002; | 384 | bpc = 0x00000002; |
| 394 | if (hp) { | 385 | if (hp) { |
| 395 | bpc |= 0x00020200; /* address and mode are 4-bit */ | 386 | bpc |= 0x00020200; /* address and mode are 4-bit */ |
| 396 | bpp = 4; /* dummy cycles */ | 387 | bpp |= BSPI_BPP_MODE_SELECT_MASK; |
| 397 | bpp |= BSPI_BPP_ADDR_SELECT_MASK; | ||
| 398 | command = OPCODE_QIOR; | ||
| 399 | if (spans_4byte) | ||
| 400 | command = OPCODE_QIOR_4B; | ||
| 401 | } else { | ||
| 402 | command = SPINOR_OP_READ_1_1_4; | ||
| 403 | if (spans_4byte) | ||
| 404 | command = SPINOR_OP_READ_1_1_4_4B; | ||
| 405 | } | 388 | } |
| 406 | break; | 389 | break; |
| 407 | default: | 390 | default: |
| 408 | rv = -EINVAL; | 391 | return -EINVAL; |
| 409 | break; | ||
| 410 | } | 392 | } |
| 411 | 393 | ||
| 412 | if (rv == 0) | 394 | bcm_qspi_bspi_set_xfer_params(qspi, command, bpp, bpc, flex_mode); |
| 413 | bcm_qspi_bspi_set_xfer_params(qspi, command, bpp, bpc, | ||
| 414 | flex_mode); | ||
| 415 | 395 | ||
| 416 | return rv; | 396 | return 0; |
| 417 | } | 397 | } |
| 418 | 398 | ||
| 419 | static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width, | 399 | static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, |
| 420 | int addrlen, int hp) | 400 | struct spi_flash_read_message *msg, |
| 401 | int hp) | ||
| 421 | { | 402 | { |
| 403 | int width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE; | ||
| 404 | int addrlen = msg->addr_width; | ||
| 422 | u32 data = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); | 405 | u32 data = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); |
| 423 | 406 | ||
| 424 | dev_dbg(&qspi->pdev->dev, "set override mode w %x addrlen %x hp %d\n", | 407 | dev_dbg(&qspi->pdev->dev, "set override mode w %x addrlen %x hp %d\n", |
| @@ -430,7 +413,6 @@ static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width, | |||
| 430 | data &= ~(BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD | | 413 | data &= ~(BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD | |
| 431 | BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL); | 414 | BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL); |
| 432 | break; | 415 | break; |
| 433 | |||
| 434 | case SPI_NBITS_QUAD: | 416 | case SPI_NBITS_QUAD: |
| 435 | /* clear dual mode and set quad mode */ | 417 | /* clear dual mode and set quad mode */ |
| 436 | data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL; | 418 | data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL; |
| @@ -455,15 +437,17 @@ static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width, | |||
| 455 | /* set the override mode */ | 437 | /* set the override mode */ |
| 456 | data |= BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; | 438 | data |= BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; |
| 457 | bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, data); | 439 | bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, data); |
| 458 | bcm_qspi_bspi_set_xfer_params(qspi, SPINOR_OP_READ_FAST, 0, 0, 0); | 440 | bcm_qspi_bspi_set_xfer_params(qspi, msg->read_opcode, 0, 0, 0); |
| 459 | 441 | ||
| 460 | return 0; | 442 | return 0; |
| 461 | } | 443 | } |
| 462 | 444 | ||
| 463 | static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi, | 445 | static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi, |
| 464 | int width, int addrlen, int hp) | 446 | struct spi_flash_read_message *msg, int hp) |
| 465 | { | 447 | { |
| 466 | int error = 0; | 448 | int error = 0; |
| 449 | int width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE; | ||
| 450 | int addrlen = msg->addr_width; | ||
| 467 | 451 | ||
| 468 | /* default mode */ | 452 | /* default mode */ |
| 469 | qspi->xfer_mode.flex_mode = true; | 453 | qspi->xfer_mode.flex_mode = true; |
| @@ -475,23 +459,13 @@ static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi, | |||
| 475 | mask = BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; | 459 | mask = BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; |
| 476 | if (val & mask || qspi->s3_strap_override_ctrl & mask) { | 460 | if (val & mask || qspi->s3_strap_override_ctrl & mask) { |
| 477 | qspi->xfer_mode.flex_mode = false; | 461 | qspi->xfer_mode.flex_mode = false; |
| 478 | bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, | 462 | bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0); |
| 479 | 0); | 463 | error = bcm_qspi_bspi_set_override(qspi, msg, hp); |
| 480 | |||
| 481 | if ((val | qspi->s3_strap_override_ctrl) & | ||
| 482 | BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL) | ||
| 483 | width = SPI_NBITS_DUAL; | ||
| 484 | else if ((val | qspi->s3_strap_override_ctrl) & | ||
| 485 | BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD) | ||
| 486 | width = SPI_NBITS_QUAD; | ||
| 487 | |||
| 488 | error = bcm_qspi_bspi_set_override(qspi, width, addrlen, | ||
| 489 | hp); | ||
| 490 | } | 464 | } |
| 491 | } | 465 | } |
| 492 | 466 | ||
| 493 | if (qspi->xfer_mode.flex_mode) | 467 | if (qspi->xfer_mode.flex_mode) |
| 494 | error = bcm_qspi_bspi_set_flex_mode(qspi, width, addrlen, hp); | 468 | error = bcm_qspi_bspi_set_flex_mode(qspi, msg, hp); |
| 495 | 469 | ||
| 496 | if (error) { | 470 | if (error) { |
| 497 | dev_warn(&qspi->pdev->dev, | 471 | dev_warn(&qspi->pdev->dev, |
| @@ -981,7 +955,7 @@ static int bcm_qspi_flash_read(struct spi_device *spi, | |||
| 981 | struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); | 955 | struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); |
| 982 | int ret = 0; | 956 | int ret = 0; |
| 983 | bool mspi_read = false; | 957 | bool mspi_read = false; |
| 984 | u32 io_width, addrlen, addr, len; | 958 | u32 addr, len; |
| 985 | u_char *buf; | 959 | u_char *buf; |
| 986 | 960 | ||
| 987 | buf = msg->buf; | 961 | buf = msg->buf; |
| @@ -1010,9 +984,7 @@ static int bcm_qspi_flash_read(struct spi_device *spi, | |||
| 1010 | if (mspi_read) | 984 | if (mspi_read) |
| 1011 | return bcm_qspi_mspi_flash_read(spi, msg); | 985 | return bcm_qspi_mspi_flash_read(spi, msg); |
| 1012 | 986 | ||
| 1013 | io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE; | 987 | ret = bcm_qspi_bspi_set_mode(qspi, msg, -1); |
| 1014 | addrlen = msg->addr_width; | ||
| 1015 | ret = bcm_qspi_bspi_set_mode(qspi, io_width, addrlen, -1); | ||
| 1016 | 988 | ||
| 1017 | if (!ret) | 989 | if (!ret) |
| 1018 | ret = bcm_qspi_bspi_flash_read(spi, msg); | 990 | ret = bcm_qspi_bspi_flash_read(spi, msg); |
| @@ -1422,6 +1394,11 @@ static int __maybe_unused bcm_qspi_suspend(struct device *dev) | |||
| 1422 | { | 1394 | { |
| 1423 | struct bcm_qspi *qspi = dev_get_drvdata(dev); | 1395 | struct bcm_qspi *qspi = dev_get_drvdata(dev); |
| 1424 | 1396 | ||
| 1397 | /* store the override strap value */ | ||
| 1398 | if (!bcm_qspi_bspi_ver_three(qspi)) | ||
| 1399 | qspi->s3_strap_override_ctrl = | ||
| 1400 | bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); | ||
| 1401 | |||
| 1425 | spi_master_suspend(qspi->master); | 1402 | spi_master_suspend(qspi->master); |
| 1426 | clk_disable(qspi->clk); | 1403 | clk_disable(qspi->clk); |
| 1427 | bcm_qspi_hw_uninit(qspi); | 1404 | bcm_qspi_hw_uninit(qspi); |
