diff options
author | PixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com> | 2022-11-20 18:52:34 -0800 |
---|---|---|
committer | SecurityBot <android-nexus-securitybot@system.gserviceaccount.com> | 2022-11-20 18:52:34 -0800 |
commit | eb6196f9b97c917f14c2e179f2224e7b10b3a353 (patch) | |
tree | c2903401d7683e82831ca1e3f53a8dc40a50b733 | |
parent | 67a4a82662db5ad1bcedcb761b2a5bd206ee166e (diff) | |
parent | 3e559bb2d012572daeaf5630cece699be6611302 (diff) | |
download | uwb-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.h | 6 | ||||
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_core.c | 113 | ||||
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_core.h | 4 | ||||
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_core_reg.h | 11 | ||||
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_stm.c | 38 |
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; |