summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Rocher <jeremy.rocher@qorvo.com>2022-11-18 13:06:48 +0100
committerRex Lin <rexcylin@google.com>2022-12-02 07:33:19 +0000
commit7489e25a9675becbb01e95794e44bd47402fb7cc (patch)
treef852f804f62fe70b923fd5f2085b92be24c0aed7
parentc2872d0980131d7b5671d405f6ff6a7d1e9d8fd6 (diff)
downloaduwb-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.c22
-rw-r--r--debug.h1
-rw-r--r--hsspi.c2
-rw-r--r--hsspi_coredump.c23
-rw-r--r--libqmrom/include/qmrom_spi.h5
-rw-r--r--libqmrom/src/qmrom.c21
-rw-r--r--libqmrom/src/spi_rom_protocol.c11
-rw-r--r--qm35-spi.c34
-rw-r--r--qmrom_spi.c17
9 files changed, 110 insertions, 26 deletions
diff --git a/debug.c b/debug.c
index f7f3496..e1213a4 100644
--- a/debug.c
+++ b/debug.c
@@ -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 = {
diff --git a/debug.h b/debug.h
index d054f92..2880ce1 100644
--- a/debug.h
+++ b/debug.h
@@ -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 {
diff --git a/hsspi.c b/hsspi.c
index b8329aa..34d5954 100644
--- a/hsspi.c
+++ b/hsspi.c
@@ -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);
diff --git a/qm35-spi.c b/qm35-spi.c
index 97afd0c..95d57ee 100644
--- a/qm35-spi.c
+++ b/qm35-spi.c
@@ -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;
+}