diff options
author | Jeremy Rocher <jeremy.rocher@qorvo.com> | 2022-11-18 13:06:48 +0100 |
---|---|---|
committer | Rex Lin <rexcylin@google.com> | 2022-12-02 07:33:19 +0000 |
commit | 7489e25a9675becbb01e95794e44bd47402fb7cc (patch) | |
tree | f852f804f62fe70b923fd5f2085b92be24c0aed7 | |
parent | c2872d0980131d7b5671d405f6ff6a7d1e9d8fd6 (diff) | |
download | uwb-7489e25a9675becbb01e95794e44bd47402fb7cc.tar.gz |
uwb: update uwb driver to qorvo 5.1 release
Qorvo git references
* uci-kernel-module @592af0c
* libqmrom @1bfaf2e
Features
* New coredump force command
Fixes
* Set SPI CLK at 3MHz during flashing on QM357xx-B0 only
* Check ss_ready at the end of probe to avoid false state
* Increase the ss_ready timeout and retries to allow recovery
* Register /dev/uci last to avoid crash if hsspi not ready
Bug: 260930840
Test: build pass
Change-Id: I78acfd15102b95728d3c5f3989ddbf62880f82f7
Signed-off-by: Jeremy Rocher <jeremy.rocher@qorvo.com>
-rw-r--r-- | debug.c | 22 | ||||
-rw-r--r-- | debug.h | 1 | ||||
-rw-r--r-- | hsspi.c | 2 | ||||
-rw-r--r-- | hsspi_coredump.c | 23 | ||||
-rw-r--r-- | libqmrom/include/qmrom_spi.h | 5 | ||||
-rw-r--r-- | libqmrom/src/qmrom.c | 21 | ||||
-rw-r--r-- | libqmrom/src/spi_rom_protocol.c | 11 | ||||
-rw-r--r-- | qm35-spi.c | 34 | ||||
-rw-r--r-- | qmrom_spi.c | 17 |
9 files changed, 110 insertions, 26 deletions
@@ -247,6 +247,27 @@ static ssize_t debug_coredump_read(struct file *filep, char __user *buff, return simple_read_from_buffer(buff, count, off, cd, cd_len); } +static ssize_t debug_coredump_write(struct file *filp, const char __user *buff, + size_t count, loff_t *off) +{ + struct debug *debug; + u8 force; + + debug = priv_from_file(filp); + + if (kstrtou8_from_user(buff, count, 10, &force)) + return -EFAULT; + + if (debug->coredump_ops && force != 0) + debug->coredump_ops->coredump_force(debug); + else if (force == 0) + pr_warn("qm35: write non null value to force coredump\n"); + else + return -ENOSYS; + + return count; +} + static int debug_debug_certificate_open(struct inode *inodep, struct file *filep) { struct debug *debug = priv_from_file(filep); @@ -348,6 +369,7 @@ static const struct file_operations debug_traces_fops = { static const struct file_operations debug_coredump_fops = { .owner = THIS_MODULE, .read = debug_coredump_read, + .write = debug_coredump_write, }; static const struct file_operations debug_debug_certificate_fops = { @@ -51,6 +51,7 @@ struct debug_trace_ops { struct debug_coredump_ops { char *(*coredump_get)(struct debug *dbg, size_t *len); + int (*coredump_force)(struct debug *dbg); }; struct debug { @@ -201,7 +201,7 @@ static int spi_xfer(struct hsspi *hsspi, const void *tx, void *rx, .len = length, }, }; - int ret, retry = 3; + int ret, retry = 20; hsspi->soc->flags = 0; hsspi->soc->ul = 0; diff --git a/hsspi_coredump.c b/hsspi_coredump.c index 209a0e1..8038209 100644 --- a/hsspi_coredump.c +++ b/hsspi_coredump.c @@ -32,6 +32,7 @@ #define COREDUMP_HEADER_NTF 0x00 #define COREDUMP_BODY_NTF 0x01 #define COREDUMP_RCV_STATUS 0x02 +#define COREDUMP_FORCE_CMD 0x03 #define COREDUMP_RCV_NACK 0x00 #define COREDUMP_RCV_ACK 0x01 @@ -296,8 +297,30 @@ char *debug_coredump_get(struct debug *dbg, size_t *len) return data; } +int debug_coredump_force(struct debug *dbg) +{ + struct coredump_packet *p; + struct coredump_common_hdr hdr = { .cmd_id = COREDUMP_FORCE_CMD }; + struct qm35_ctx *qm35_hdl; + + pr_info("qm35: force coredump"); + + qm35_hdl = container_of(dbg, struct qm35_ctx, debug); + + p = coredump_packet_alloc(sizeof(hdr)); + if (!p) + return -ENOMEM; + + memcpy(p->blk.data, &hdr, sizeof(hdr)); + + return hsspi_send(&qm35_hdl->hsspi, &qm35_hdl->coredump_layer.hlayer, + &p->blk); +} + + static const struct debug_coredump_ops debug_coredump_ops = { .coredump_get = debug_coredump_get, + .coredump_force = debug_coredump_force, }; int coredump_layer_init(struct coredump_layer *layer, struct debug *debug) diff --git a/libqmrom/include/qmrom_spi.h b/libqmrom/include/qmrom_spi.h index 35cce45..2266149 100644 --- a/libqmrom/include/qmrom_spi.h +++ b/libqmrom/include/qmrom_spi.h @@ -23,7 +23,8 @@ struct firmware { #include <linux/firmware.h> #endif -#define DEFAULT_SPI_CLOCKRATE 750000 +#define DEFAULT_SPI_CLOCKRATE_A0 750000 +#define DEFAULT_SPI_CLOCKRATE 3000000 #define DEFAULT_SPI_LATENCY_MS 2 #define SPI_ERR_NOCHAN SPI_ERR_BASE - 1 @@ -50,5 +51,7 @@ int qmrom_spi_reset_device(void *reset_handle); const struct firmware *qmrom_spi_get_firmware(void *handle, enum chip_revision_e revision, int lcs_state); void qmrom_spi_release_firmware(const struct firmware *fw); int qmrom_spi_wait_for_ready_line(void *handle, unsigned int timeout_ms); +void qmrom_spi_set_freq(unsigned int freq); +unsigned int qmrom_spi_get_freq(void); #endif /* __QMROM_SPI_H__ */ diff --git a/libqmrom/src/qmrom.c b/libqmrom/src/qmrom.c index 1962434..c76baae 100644 --- a/libqmrom/src/qmrom.c +++ b/libqmrom/src/qmrom.c @@ -237,6 +237,7 @@ int qmrom_get_soc_info(void *spi_handle, struct stc *hstc, *sstc; uint8_t *payload; int i; + enum chip_revision_e revision; rc = qmrom_allocate_stcs(&hstc, &sstc); if (rc) @@ -247,6 +248,22 @@ int qmrom_get_soc_info(void *spi_handle, if (rc) goto out; + LOG_INFO("Getting the chip revision\n"); + rc = qmrom_chip_revision(spi_handle, sstc, hstc, &revision); + if (rc) + goto out; + + if (revision == CHIP_REVISION_A0) { + LOG_WARN("%s: SoC info not supported on chip revision A0\n", __func__); + rc = -1; + goto out; + } + + LOG_INFO("Rebooting the board\n"); + rc = qmrom_reboot_bootloader(spi_handle, reset_fn, reset_handle); + if (rc) + goto out; + /* Sending command... */ hstc->payload[0] = 3; rc = spi_proto_prepare_write_cmd(spi_handle, 1, @@ -336,7 +353,7 @@ int qmrom_download_fw(void *spi_handle, if (rc) goto fail; - LOG_INFO("Getting the board revision\n"); + LOG_INFO("Getting the chip revision\n"); rc = qmrom_chip_revision(spi_handle, sstc, hstc, &revision); if (rc) goto fail; @@ -456,7 +473,7 @@ static int qmrom_chip_revision(void *spi_handle, rc = 1; } - LOG_INFO("detected board revision: %02x\n", *revision); + LOG_INFO("detected chip revision: %02x\n", *revision); out: return rc; } diff --git a/libqmrom/src/spi_rom_protocol.c b/libqmrom/src/spi_rom_protocol.c index 951ac26..a627eaa 100644 --- a/libqmrom/src/spi_rom_protocol.c +++ b/libqmrom/src/spi_rom_protocol.c @@ -65,7 +65,16 @@ int spi_proto_prepare_write_cmd(void *spi_handle, int do_exp_resp, enum chip_revision_e revision) { uint8_t dev_ready_flag = SPI_DEVICE_READY_FLAGS; - int rc = spi_proto_wait_for_device_flag(spi_handle, + int rc; + + if (revision == CHIP_REVISION_A0) { + qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE_A0); + } + else { + qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE); + } + + rc = spi_proto_wait_for_device_flag(spi_handle, dev_ready_flag, sstc, hstc, SPI_DEVICE_POLL_RETRY); @@ -471,10 +471,6 @@ static int hsspi_irqs_setup(struct qm35_ctx *qm35_ctx) if (ret) return ret; - /* we can have miss an edge */ - if (gpiod_get_value(qm35_ctx->gpio_ss_rdy)) - hsspi_set_spi_slave_ready(&qm35_ctx->hsspi); - /* get SS_IRQ GPIO */ qm35_ctx->gpio_ss_irq = devm_gpiod_get_optional( &qm35_ctx->spi->dev, "ss-irq", GPIOD_IN); @@ -653,25 +649,17 @@ static int qm35_probe(struct spi_device *spi) uci_misc->fops = &uci_fops; uci_misc->parent = &spi->dev; - ret = misc_register(&qm35_ctx->uci_dev); - if (ret) { - dev_err(&spi->dev, "Failed to register uci device\n"); - goto poweroff; - } - - dev_info(&spi->dev, "Registered: [%s] misc device\n", uci_misc->name); - qm35_ctx->state = QM35_CTRL_STATE_UNKNOWN; if (flash_on_probe) { ret = qm_firmware_load(qm35_ctx); if (ret) - goto misc_deregister; + goto poweroff; } ret = hsspi_init(&qm35_ctx->hsspi, spi); if (ret) - goto misc_deregister; + goto poweroff; ret = uci_layer_init(&qm35_ctx->uci_layer); if (ret) @@ -709,6 +697,18 @@ static int qm35_probe(struct spi_device *spi) hsspi_start(&qm35_ctx->hsspi); + /* we can have missed an edge */ + if (gpiod_get_value(qm35_ctx->gpio_ss_rdy)) + hsspi_set_spi_slave_ready(&qm35_ctx->hsspi); + + ret = misc_register(&qm35_ctx->uci_dev); + if (ret) { + dev_err(&spi->dev, "Failed to register uci device\n"); + goto log_layer_unregister; + } + + dev_info(&spi->dev, "Registered: [%s] misc device\n", uci_misc->name); + dev_info(&spi->dev, "QM35 spi driver probed\n"); return 0; @@ -728,8 +728,6 @@ uci_layer_deinit: uci_layer_deinit(&qm35_ctx->uci_layer); hsspi_deinit: hsspi_deinit(&qm35_ctx->hsspi); -misc_deregister: - misc_deregister(&qm35_ctx->uci_dev); poweroff: qm35_regulators_set(qm35_ctx, false); return ret; @@ -739,6 +737,8 @@ static int qm35_remove(struct spi_device *spi) { struct qm35_ctx *qm35_hdl = spi_get_drvdata(spi); + misc_deregister(&qm35_hdl->uci_dev); + hsspi_stop(&qm35_hdl->hsspi); hsspi_unregister(&qm35_hdl->hsspi, &qm35_hdl->log_layer.hlayer); @@ -752,8 +752,6 @@ static int qm35_remove(struct spi_device *spi) hsspi_deinit(&qm35_hdl->hsspi); - misc_deregister(&qm35_hdl->uci_dev); - qm35_regulators_set(qm35_hdl, false); dev_info(&spi->dev, "Deregistered: [%s] misc device\n", diff --git a/qmrom_spi.c b/qmrom_spi.c index ca17ac1..123c534 100644 --- a/qmrom_spi.c +++ b/qmrom_spi.c @@ -34,6 +34,8 @@ #include "qm35.h" static const char *fwname = NULL; +// Initialize to the lowest default frequency +static unsigned int speed_hz = DEFAULT_SPI_CLOCKRATE_A0; void qmrom_set_fwname(const char *name) { @@ -49,7 +51,7 @@ int qmrom_spi_transfer(void *handle, char *rbuf, const char *wbuf, size_t size) .tx_buf = wbuf, .rx_buf = rbuf, .len = size, - .speed_hz = DEFAULT_SPI_CLOCKRATE, + .speed_hz = qmrom_spi_get_freq(), }, }; @@ -66,8 +68,7 @@ int qmrom_spi_set_cs_level(void *handle, int level) .tx_buf = &dummy, .len = 1, .cs_change = !level, - .speed_hz = DEFAULT_SPI_CLOCKRATE, - + .speed_hz = qmrom_spi_get_freq(), }, }; @@ -129,3 +130,13 @@ int qmrom_spi_wait_for_ready_line(void *handle, unsigned int timeout_ms) return 0; } + +void qmrom_spi_set_freq(unsigned int freq) +{ + speed_hz = freq; +} + +unsigned int qmrom_spi_get_freq() +{ + return speed_hz; +} |