summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com>2022-11-20 18:52:34 -0800
committerSecurityBot <android-nexus-securitybot@system.gserviceaccount.com>2022-11-20 18:52:34 -0800
commiteb6196f9b97c917f14c2e179f2224e7b10b3a353 (patch)
treec2903401d7683e82831ca1e3f53a8dc40a50b733
parent67a4a82662db5ad1bcedcb761b2a5bd206ee166e (diff)
parent3e559bb2d012572daeaf5630cece699be6611302 (diff)
downloaduwb-eb6196f9b97c917f14c2e179f2224e7b10b3a353.tar.gz
Merge android13-gs-pixel-5.10-tm-qpr3 into android13-gs-pixel-5.10-udc
SBMerger: 478053055 Change-Id: I54404c85ae98547362d9ca15b0ea18656007c9bd Signed-off-by: SecurityBot <android-nexus-securitybot@system.gserviceaccount.com>
-rw-r--r--kernel/drivers/net/ieee802154/dw3000.h6
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core.c113
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core.h4
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core_reg.h11
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_stm.c38
5 files changed, 146 insertions, 26 deletions
diff --git a/kernel/drivers/net/ieee802154/dw3000.h b/kernel/drivers/net/ieee802154/dw3000.h
index e21ef8e..6fb5d5e 100644
--- a/kernel/drivers/net/ieee802154/dw3000.h
+++ b/kernel/drivers/net/ieee802154/dw3000.h
@@ -585,6 +585,7 @@ struct dw3000_rx_ctx {
* @dw3000_pid: PID the dw3000 state machine thread
* @restricted_channels: bit field of restricted channels
* @tx_rf2: parameter to enable the tx on rf2 port
+ * @rx_rf2: parameter to enable the rx on rf2 port
* @cir_data_changed: true if buffer data have been reallocated
* @full_cia_read: CIA registers fully loaded into cir_data struct
* @cir_data: allocated CIR exploitation data
@@ -703,6 +704,8 @@ struct dw3000 {
u16 restricted_channels;
/* enable tx on RF2 port */
u8 tx_rf2;
+ /* enable rx on RF2 port */
+ u8 rx_rf2;
/* Channel impulse response data */
bool cir_data_changed;
bool full_cia_read;
@@ -714,7 +717,8 @@ struct dw3000 {
/* Buffer for queued transfers */
char *msg_queue_buf;
char *msg_queue_buf_pos;
-
+ /* dw3000 thread clamp value */
+ int min_clamp_value;
/* Insert new fields before this line */
/* Shared message protected by a mutex */
diff --git a/kernel/drivers/net/ieee802154/dw3000_core.c b/kernel/drivers/net/ieee802154/dw3000_core.c
index 4b384b9..932f0db 100644
--- a/kernel/drivers/net/ieee802154/dw3000_core.c
+++ b/kernel/drivers/net/ieee802154/dw3000_core.c
@@ -187,8 +187,8 @@ const struct dw3000_chip_version dw3000_chip_versions[] = {
#define DW3000_TXRXSWITCH_TX 0x01011100
#define DW3000_TXRXSWITCH_AUTO 0x1C000000
-#define DW3000_RF_TXCTRL_CH5 0x1C071134UL
-#define DW3000_RF_TXCTRL_CH9 0x1C010034UL
+#define DW3000_RF_TXCTRL_CH5 0x1C081134UL
+#define DW3000_RF_TXCTRL_CH9 0x1C020034UL
#define DW3000_RF_TXCTRL_LO_B2 0x0E
#define DW3000_RF_PLL_CFG_CH5 0x1F3C
#define DW3000_RF_PLL_CFG_CH9 0x0F3C
@@ -297,6 +297,14 @@ enum ciadiag_dbl_options {
/* Disable CIA diagnostic. CIACONFIG's bit-4 in RX_ANTENNA_DELAY + 1 */
#define DW3000_CIA_CONFIG_DIAG_OFF (0x1 << 4)
+/* LDO VOUT value */
+#define DW3000_RF_LDO_VOUT 0x0D7FFFFFUL
+/* RF SWITCH RX RF2 */
+#define DW3000_RF_SWITCH_RX_RF2 0x2131
+
+/* PLL common value */
+#define DW3000_RF_PLL_COMMON 0xE104
+
struct dw3000_ciadiag_reg_info {
u32 diag1;
u32 diag12;
@@ -1379,14 +1387,44 @@ int dw3000_clear_spi_collision_status(struct dw3000 *dw, u8 clear_bits)
return rc;
}
-
-int dw3000_change_tx_rf1_to_rf2(struct dw3000 *dw, bool tx)
+/**
+ * dw3000_change_tx_rf_port() - Enable TX on RF2 port.
+ * @dw: the DW device on which the SPI transfer will occurs
+ * @use_rf2: variable to trigger the SWITCH to RF2
+ *
+ * Return: 0 on success, else a negative error code.
+ */
+static int dw3000_change_tx_rf_port(struct dw3000 *dw, bool use_rf2)
{
int rc;
- if (tx)
- rc = dw3000_reg_write32(dw, DW3000_RF_SWITCH_CTRL_ID, 0, 0x1C000050);
- else
- rc = dw3000_reg_write32(dw, DW3000_RF_SWITCH_CTRL_ID, 0, 0x1C000000);
+ u32 val = DW3000_TXRXSWITCH_AUTO |
+ ((u32)use_rf2
+ << DW3000_RF_SWITCH_CTRL_ANT_TXRX_TXPORT_BIT_OFFSET) |
+ ((u32)use_rf2
+ << DW3000_RF_SWITCH_CTRL_ANT_TXRX_MODE_OVR_BIT_OFFSET);
+ rc = dw3000_reg_write32(dw, DW3000_RF_SWITCH_CTRL_ID, 0, val);
+ if (!rc)
+ dw->tx_rf2 = use_rf2;
+ return rc;
+}
+
+/**
+ * dw3000_change_rx_rf_port() - Enable RX on RF2 port.
+ * @dw: the DW device on which the SPI transfer will occurs
+ * @use_rf2: variable to trigger the SWITCH to RF2
+ *
+ * Return: 0 on success, else a negative error code.
+ */
+static int dw3000_change_rx_rf_port(struct dw3000 *dw, bool use_rf2)
+{
+ int rc = 0;
+ u32 val;
+ if (use_rf2) {
+ val =DW3000_TXRXSWITCH_AUTO | DW3000_RF_SWITCH_RX_RF2;
+ rc = dw3000_reg_write32(dw, DW3000_RF_SWITCH_CTRL_ID, 0, val);
+ if (!rc)
+ dw->rx_rf2 = use_rf2;
+ }
return rc;
}
@@ -1796,6 +1834,12 @@ static int dw3000_power_supply(struct dw3000 *dw, int onoff)
onoff ? "enable" : "disable", rc);
return rc;
}
+ /* Set 2p5 reg to 2.7V */
+ rc = regulator_set_voltage(power->regulator_2p5, 2700000, 2700000);
+ if (rc < 0) {
+ dev_err(dw->dev, "regulator failed to set voltage :%d\n", rc);
+ return rc;
+ }
rc = dw3000_power_supply_one(power->regulator_vdd, onoff);
if (rc < 0) {
@@ -1823,6 +1867,7 @@ static int dw3000_power_supply(struct dw3000 *dw, int onoff)
static int dw3000_reset_assert(struct dw3000 *dw, bool reset)
{
int rc;
+ int value;
if (!gpio_is_valid(dw->reset_gpio)) {
dev_err(dw->dev, "invalid reset gpio\n");
@@ -1838,10 +1883,22 @@ static int dw3000_reset_assert(struct dw3000 *dw, bool reset)
} else {
/* Release RESET GPIO.
* Reset should be open drain, or switched to input whenever not driven
- * low. It should not be driven high. */
+ * low. It should not be driven high during chip cold boot process. */
rc = gpio_direction_input(dw->reset_gpio);
- if (rc)
+ if (rc) {
dev_err(dw->dev, "Could not set reset gpio as input\n");
+ return rc;
+ }
+ /* check if dw3000 finishes cold boot */
+ value = gpio_get_value(dw->reset_gpio);
+ if (!value) {
+ return -EPROBE_DEFER;
+ }
+
+ /* set pin to output and drive high */
+ rc = gpio_direction_output(dw->reset_gpio, 1);
+ if (rc)
+ dev_err(dw->dev, "Could not set reset gpio as output\n");
}
return rc;
}
@@ -2629,7 +2686,7 @@ int dw3000_do_rx_enable(struct dw3000 *dw,
if (unlikely(rc))
goto fail;
/* Ensure correct RX antennas are selected. */
- rc = dw3000_set_rx_antennas(dw, config->ant_set_id, pdoa_enabled);
+ rc = dw3000_set_rx_antennas(dw, config->ant_set_id, pdoa_enabled, frame_idx);
if (unlikely(rc))
goto fail;
if (config->flags & MCPS802154_RX_FRAME_CONFIG_AACK) {
@@ -4253,6 +4310,11 @@ static inline int dw3000_configure_rf(struct dw3000 *dw)
rc = dw3000_reg_write16(dw, DW3000_PLL_CFG_ID, 0, rf_pll_cfg);
if (rc)
return rc;
+
+ rc = dw3000_reg_write16(dw, DW3000_PLL_COMMON_ID, 0, DW3000_RF_PLL_COMMON);
+ if (rc)
+ return rc;
+
rc = dw3000_reg_write8(dw, DW3000_LDO_RLOAD_ID, 1,
DW3000_LDO_RLOAD_VAL_B1);
if (rc)
@@ -4390,6 +4452,8 @@ int dw3000_configure_chan(struct dw3000 *dw)
rc = dw3000_configure_rf(dw);
if (rc)
return rc;
+ /* Disable AGC */
+ dw3000_reg_modify32(dw, DW3000_AGC_CFG_ID, 0, DW3000_AGC_DIS_MASK, 0);
/* Configure DGC. */
return dw3000_configure_dgc(dw);
}
@@ -5213,6 +5277,8 @@ static int dw3000_configure(struct dw3000 *dw)
/* Update configuration dependent timings */
dw3000_update_timings(dw);
+ /* update VOUT */
+ rc = dw3000_reg_write32(dw, DW3000_LDO_VOUT_ID, 0, DW3000_RF_LDO_VOUT);
return rc;
}
@@ -6423,10 +6489,8 @@ int dw3000_set_tx_antenna(struct dw3000 *dw, int ant_set_id)
/* Retrieve antenna GPIO configuration from calibration data */
ant_calib = &dw->calib_data.ant[ant_idx1];
/* switching to RF2 port for TX if necessary */
- if (ant_calib->port == 1) {
- dw3000_change_tx_rf1_to_rf2(dw, true);
- dw->tx_rf2 = 1;
- }
+ if (ant_calib->port == 1 || dw->tx_rf2)
+ dw3000_change_tx_rf_port(dw, ant_calib->port == 1);
/* Set GPIO state according config to select this antenna */
rc = dw3000_set_antenna_gpio(dw, ant_calib);
@@ -6443,10 +6507,11 @@ int dw3000_set_tx_antenna(struct dw3000 *dw, int ant_set_id)
* @dw: The DW device.
* @ant_set_id: The antennas set id to use
* @pdoa_enabled: True if PDoA is enabled
+ * @frame_idx: the id of the frame to be rcvd
*
* Return: zero on success, else a negative error code.
*/
-int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, bool pdoa_enabled)
+int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, bool pdoa_enabled, int frame_idx)
{
struct dw3000_config *config = &dw->config;
struct dw3000_antenna_calib *ant_calib;
@@ -6455,9 +6520,6 @@ int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, bool pdoa_enabled)
/* Sanity checks first */
if (ant_set_id < 0 || ant_set_id >= ANTSET_ID_MAX)
return -EINVAL;
- if (dw->tx_rf2) {
- dw3000_change_tx_rf1_to_rf2(dw, false);
- }
/* Retrieve RX antennas configuration from antenna set id */
dw3000_calib_ant_set_id_to_ant(ant_set_id, &ant_idx1, &ant_idx2);
if (pdoa_enabled && (ant_idx1 < 0 || ant_idx2 < 0)) {
@@ -6470,6 +6532,16 @@ int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, bool pdoa_enabled)
if (ant_idx1 >= 0) {
ant_calib = &dw->calib_data.ant[ant_idx1];
port = ant_calib->port; /* Save port for later check */
+ if (((ant_calib->port == 1) || dw->rx_rf2) && ant_idx2 < 0) {
+ dw3000_change_rx_rf_port(dw, true);
+ } else if (ant_calib->port == 1 && ant_idx2 > 0) {
+ if (frame_idx == 5)
+ dw3000_change_rx_rf_port(dw, true);
+ else
+ dw3000_change_rx_rf_port(dw, false);
+ } else {
+ dw3000_change_rx_rf_port(dw, false);
+ }
if (ant_idx1 != config->ant[port]) {
/* Set GPIO state according config for this first antenna */
rc = dw3000_set_antenna_gpio(dw, ant_calib);
@@ -7453,6 +7525,9 @@ static inline int dw3000_isr_handle_spi_ready(struct dw3000 *dw,
/* TODO: So, just add below this line more required unsaved registers
* setup. */
+ rc = dw3000_reg_write32(dw, DW3000_LDO_VOUT_ID, 0, DW3000_RF_LDO_VOUT);
+ if (rc)
+ return rc;
setuperror:
#ifdef CONFIG_DW3000_DEBUG
diff --git a/kernel/drivers/net/ieee802154/dw3000_core.h b/kernel/drivers/net/ieee802154/dw3000_core.h
index e3c28a8..aa7c4ed 100644
--- a/kernel/drivers/net/ieee802154/dw3000_core.h
+++ b/kernel/drivers/net/ieee802154/dw3000_core.h
@@ -199,7 +199,7 @@ enum spi_modes {
/* Size of RX LUT configuration tables */
#define DW3000_CONFIGMRXLUT_MAX 7
#define DW3000_DGC_CFG 0x38
-#define DW3000_DGC_CFG0 0x10000240
+#define DW3000_DGC_CFG0 0x00000240
#define DW3000_DGC_CFG1 0x1a491248
#define DW3000_DGC_CFG2 0x2db248db
@@ -419,7 +419,7 @@ int dw3000_tx_setcwtone(struct dw3000 *dw, bool on);
int dw3000_config_antenna_gpios(struct dw3000 *dw);
int dw3000_set_tx_antenna(struct dw3000 *dw, int ant_set_id);
int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id,
- bool pdoa_enabled);
+ bool pdoa_enabled, int frame_idx);
s16 dw3000_read_pdoa(struct dw3000 *dw);
s16 dw3000_pdoa_to_aoa_lut(struct dw3000 *dw, s16 pdoa_rad_q11);
diff --git a/kernel/drivers/net/ieee802154/dw3000_core_reg.h b/kernel/drivers/net/ieee802154/dw3000_core_reg.h
index 7b77584..592f582 100644
--- a/kernel/drivers/net/ieee802154/dw3000_core_reg.h
+++ b/kernel/drivers/net/ieee802154/dw3000_core_reg.h
@@ -649,6 +649,7 @@
#define DW3000_AGC_CFG_ID 0x30014
#define DW3000_AGC_CFG_LEN (4U)
#define DW3000_AGC_CFG_MASK 0xFFFFFFFFUL
+#define DW3000_AGC_DIS_MASK 0xFFFFFFFEUL
/* Register DGC_CFG. */
#define DW3000_DGC_CFG_ID 0x30018
@@ -1181,6 +1182,8 @@
#define DW3000_RF_SWITCH_CTRL_ANT_TXRX_MODE_OVR_BIT_OFFSET (4U)
#define DW3000_RF_SWITCH_CTRL_ANT_TXRX_MODE_OVR_BIT_LEN (1U)
#define DW3000_RF_SWITCH_CTRL_ANT_TXRX_MODE_OVR_BIT_MASK 0x10U
+#define DW3000_RF_SWITCH_CTRL_ANT_TXRX_NOTOGGLE_BIT_MASK 0x1U
+#define DW3000_RF_SWITCH_CTRL_ANT_TXRX_NOTOGGLE_LEN (0U)
/* register TX_CTRL_LO */
#define DW3000_TX_CTRL_LO_ID 0x70018
@@ -1368,6 +1371,9 @@
#define DW3000_LDO_CTRL_LDO_VDDMS1_EN_BIT_LEN (1U)
#define DW3000_LDO_CTRL_LDO_VDDMS1_EN_BIT_MASK 0x1U
+/* register LDO_VOUT*/
+#define DW3000_LDO_VOUT_ID 0x7004C
+
/* register LDO_RLOAD */
#define DW3000_LDO_RLOAD_ID 0x70050
@@ -1402,6 +1408,11 @@
/* register PLL_CFG */
#define DW3000_PLL_CFG_ID 0x90000
+/* register PLL_COMMON */
+#define DW3000_PLL_COMMON_ID 0x90010
+#define DW3000_PLL_COMMON_LEN (2U)
+#define DW3000_PLL_COMMON_MASK 0x0000FFFFUL
+
/* register XTAL */
#define DW3000_XTAL_ID 0x90014
#define DW3000_XTAL_TRIM_BIT_OFFSET (0U)
diff --git a/kernel/drivers/net/ieee802154/dw3000_stm.c b/kernel/drivers/net/ieee802154/dw3000_stm.c
index 5eee5cf..5b85643 100644
--- a/kernel/drivers/net/ieee802154/dw3000_stm.c
+++ b/kernel/drivers/net/ieee802154/dw3000_stm.c
@@ -21,21 +21,50 @@
* Qorvo. Please contact Qorvo to inquire about licensing terms.
*/
#include <linux/version.h>
+#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/mutex.h>
+#include <linux/of.h>
#include "dw3000.h"
#include "dw3000_core.h"
-#define DW3000_MIN_CLAMP_VALUE 170
+#define DW3000_MIN_CLAMP_VALUE 460
/* First version with sched_setattr_nocheck: v4.16-rc1~164^2~5 */
#if (KERNEL_VERSION(4, 11, 0) <= LINUX_VERSION_CODE)
#include <uapi/linux/sched/types.h>
#endif
-static inline int dw3000_set_sched_attr(struct task_struct *p)
+static int dw3000_min_clamp_value = 0;
+
+module_param_named(min_clamp_value, dw3000_min_clamp_value, int, 0644);
+MODULE_PARM_DESC(min_clamp_value, "Sets the minimum cpu frequency the dw3000 thread must run at");
+
+
+static void dw3000_get_clamp_from_dt(struct dw3000 *dw) {
+ int dt_clamp = DW3000_MIN_CLAMP_VALUE;
+ int ret;
+
+ if (!dw->dev->of_node)
+ return;
+ /* debug value is priority */
+ if (dw3000_min_clamp_value) {
+ dw->min_clamp_value = dw3000_min_clamp_value;
+ dev_info(dw->dev, "using debug min clamp=%d\n", dw->min_clamp_value);
+ return;
+ }
+
+ ret = of_property_read_u32(dw->dev->of_node, "min_clamp", &dt_clamp);
+ if (ret) {
+ dev_err(dw->dev, "error reading dt_clamp ret=%d\n", ret);
+ }
+ dw->min_clamp_value = dt_clamp;
+ dev_info(dw->dev, "dt_clamp=%d\n", dw->min_clamp_value);
+}
+
+static inline int dw3000_set_sched_attr(struct dw3000 *dw, struct task_struct *p)
{
#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
struct sched_param sched_par = { .sched_priority = MAX_RT_PRIO - 2 };
@@ -45,7 +74,7 @@ static inline int dw3000_set_sched_attr(struct task_struct *p)
struct sched_attr attr = { .sched_policy = SCHED_FIFO,
.sched_priority = MAX_RT_PRIO - 2,
.sched_flags = SCHED_FLAG_UTIL_CLAMP_MIN,
- .sched_util_min = DW3000_MIN_CLAMP_VALUE };
+ .sched_util_min = dw->min_clamp_value };
return sched_setattr_nocheck(p, &attr);
#endif
}
@@ -312,7 +341,8 @@ int dw3000_state_init(struct dw3000 *dw, int cpu)
dw->dw3000_pid = stm->mthread->pid;
/* Increase thread priority */
- rc = dw3000_set_sched_attr(stm->mthread);
+ dw3000_get_clamp_from_dt(dw);
+ rc = dw3000_set_sched_attr(dw, stm->mthread);
if (rc)
dev_err(dw->dev, "dw3000_set_sched_attr failed: %d\n", rc);
return 0;