Explorar o código

qcacmn: Add API to read tsf time

Add API to read tsf time from scratch registers.

Change-Id: If736c31f9ae522a9f853e7b83b6b8a61cad990da
CRs-Fixed: 3287544
Amit Mehta %!s(int64=2) %!d(string=hai) anos
pai
achega
163dd20054

+ 25 - 0
dp/inc/cdp_txrx_cmn.h

@@ -2905,4 +2905,29 @@ cdp_enable_mon_reap_timer(ol_txrx_soc_handle soc,
 	return soc->ops->mon_ops->txrx_enable_mon_reap_timer(soc, source,
 							     enable);
 }
+
+/**
+ * cdp_get_tsf_time() - get tsf time
+ * @soc: Datapath soc handle
+ * @mac_id: mac_id
+ * @tsf: pointer to update tsf value
+ * @tsf_sync_soc_time: pointer to update tsf sync time
+ *
+ * Return: None.
+ */
+static inline void
+cdp_get_tsf_time(ol_txrx_soc_handle soc, uint32_t tsf_id, uint32_t mac_id,
+		 uint64_t *tsf, uint64_t *tsf_sync_soc_time)
+{
+	if (!soc) {
+		dp_cdp_debug("Invalid Instance");
+		return;
+	}
+	if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_get_tsf_time)
+		return;
+
+	soc->ops->cmn_drv_ops->txrx_get_tsf_time(soc, tsf_id, mac_id, tsf,
+						 tsf_sync_soc_time);
+}
+
 #endif /* _CDP_TXRX_CMN_H_ */

+ 4 - 0
dp/inc/cdp_txrx_ops.h

@@ -683,6 +683,10 @@ struct cdp_cmn_ops {
 					       bool mlo_peers_only);
 #endif
 	QDF_STATUS (*txrx_umac_reset_deinit)(ol_txrx_soc_handle soc);
+	void (*txrx_get_tsf_time)(struct cdp_soc_t *soc_hdl, uint32_t tsf_id,
+				  uint32_t mac_id, uint64_t *tsf,
+				  uint64_t *tsf_sync_soc_time);
+
 };
 
 struct cdp_ctrl_ops {

+ 25 - 0
dp/wifi3.0/dp_main.c

@@ -13554,6 +13554,30 @@ dp_recovery_vdev_flush_peers(struct cdp_soc_t *cdp_soc,
 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
 }
 #endif
+#ifdef QCA_GET_TSF_VIA_REG
+/**
+ * dp_get_tsf_time() - get tsf time
+ * @soc: Datapath soc handle
+ * @mac_id: mac_id
+ * @tsf: pointer to update tsf value
+ * @tsf_sync_soc_time: pointer to update tsf sync time
+ *
+ * Return: None.
+ */
+static inline void
+dp_get_tsf_time(struct cdp_soc_t *soc_hdl, uint32_t tsf_id, uint32_t mac_id,
+		uint64_t *tsf, uint64_t *tsf_sync_soc_time)
+{
+	hal_get_tsf_time(((struct dp_soc *)soc_hdl)->hal_soc, tsf_id, mac_id,
+			 tsf, tsf_sync_soc_time);
+}
+#else
+static inline void
+dp_get_tsf_time(struct cdp_soc_t *soc_hdl, uint32_t tsf_id, uint32_t mac_id,
+		uint64_t *tsf, uint64_t *tsf_sync_soc_time)
+{
+}
+#endif
 
 static struct cdp_cmn_ops dp_ops_cmn = {
 	.txrx_soc_attach_target = dp_soc_attach_target_wifi3,
@@ -13675,6 +13699,7 @@ static struct cdp_cmn_ops dp_ops_cmn = {
 	.txrx_recovery_vdev_flush_peers = dp_recovery_vdev_flush_peers,
 #endif
 	.txrx_umac_reset_deinit = dp_soc_umac_reset_deinit,
+	.txrx_get_tsf_time = dp_get_tsf_time,
 };
 
 static struct cdp_ctrl_ops dp_ops_ctrl = {

+ 3 - 0
hal/wifi3.0/hal_internal.h

@@ -1199,6 +1199,9 @@ struct hal_hw_txrx_ops {
 	void (*hal_tx_vdev_mcast_ctrl_set)(hal_soc_handle_t hal_soc_hdl,
 					   uint8_t vdev_id,
 					   uint8_t mcast_ctrl_val);
+	void (*hal_get_tsf_time)(hal_soc_handle_t hal_soc_hdl, uint32_t tsf_id,
+				 uint32_t mac_id, uint64_t *tsf,
+				 uint64_t *tsf_sync_soc_time);
 };
 
 /**

+ 21 - 0
hal/wifi3.0/hal_rx.h

@@ -3018,4 +3018,25 @@ hal_rx_tlv_l3_type_get(hal_soc_handle_t hal_soc_hdl, uint8_t *buf)
 		hal_soc->ops->hal_rx_tlv_l3_type_get(buf) :
 			HAL_RX_TLV_L3_TYPE_INVALID;
 }
+
+/**
+ * hal_get_tsf_time() - Get tsf time
+ * @hal_soc_hdl: HAL soc handle
+ * @mac_id: mac_id
+ * @tsf: pointer to update tsf value
+ * @tsf_sync_soc_time: pointer to update tsf sync time
+ *
+ * Return: None.
+ */
+static inline void
+hal_get_tsf_time(hal_soc_handle_t hal_soc_hdl, uint32_t tsf_id,
+		 uint32_t mac_id, uint64_t *tsf,
+		 uint64_t *tsf_sync_soc_time)
+{
+	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
+
+	if (hal_soc->ops->hal_get_tsf_time)
+		hal_soc->ops->hal_get_tsf_time(hal_soc_hdl, tsf_id, mac_id,
+					       tsf, tsf_sync_soc_time);
+}
 #endif /* _HAL_RX_H */

+ 146 - 0
hal/wifi3.0/kiwi/hal_kiwi.c

@@ -126,6 +126,36 @@
 
 #define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2)
 
+#ifdef QCA_GET_TSF_VIA_REG
+#define PCIE_PCIE_MHI_TIME_LOW 0xA28
+#define PCIE_PCIE_MHI_TIME_HIGH 0xA2C
+
+#define PMM_REG_BASE 0xB500FC
+
+#define FW_QTIME_CYCLES_PER_10_USEC 192
+
+/* enum to indicate which scratch registers hold which value*/
+/* Obtain from pcie_reg_scratch.h? */
+enum hal_scratch_reg_enum {
+	PMM_QTIMER_GLOBAL_OFFSET_LO_US,
+	PMM_QTIMER_GLOBAL_OFFSET_HI_US,
+	PMM_MAC0_TSF1_OFFSET_LO_US,
+	PMM_MAC0_TSF1_OFFSET_HI_US,
+	PMM_MAC0_TSF2_OFFSET_LO_US,
+	PMM_MAC0_TSF2_OFFSET_HI_US,
+	PMM_MAC1_TSF1_OFFSET_LO_US,
+	PMM_MAC1_TSF1_OFFSET_HI_US,
+	PMM_MAC1_TSF2_OFFSET_LO_US,
+	PMM_MAC1_TSF2_OFFSET_HI_US,
+	PMM_MLO_OFFSET_LO_US,
+	PMM_MLO_OFFSET_HI_US,
+	PMM_TQM_CLOCK_OFFSET_LO_US,
+	PMM_TQM_CLOCK_OFFSET_HI_US,
+	PMM_Q6_CRASH_REASON,
+	PMM_PMM_REG_MAX
+};
+#endif
+
 static uint32_t hal_get_link_desc_size_kiwi(void)
 {
 	return LINK_DESC_SIZE;
@@ -1865,6 +1895,121 @@ static uint32_t hal_get_reo_qdesc_size_kiwi(uint32_t ba_window_size, int tid)
 		sizeof(struct rx_reo_queue_1k);
 }
 
+#ifdef QCA_GET_TSF_VIA_REG
+static inline void
+hal_get_tsf_enum(uint32_t tsf_id, uint32_t mac_id,
+		 enum hal_scratch_reg_enum *tsf_enum_low,
+		 enum hal_scratch_reg_enum *tsf_enum_hi)
+{
+	if (mac_id == 0) {
+		if (tsf_id == 0) {
+			*tsf_enum_low = PMM_MAC0_TSF1_OFFSET_LO_US;
+			*tsf_enum_hi = PMM_MAC0_TSF1_OFFSET_HI_US;
+		} else if (tsf_id == 1) {
+			*tsf_enum_low = PMM_MAC0_TSF2_OFFSET_LO_US;
+			*tsf_enum_hi = PMM_MAC0_TSF2_OFFSET_HI_US;
+		}
+	} else	if (mac_id == 1) {
+		if (tsf_id == 0) {
+			*tsf_enum_low = PMM_MAC1_TSF1_OFFSET_LO_US;
+			*tsf_enum_hi = PMM_MAC1_TSF1_OFFSET_HI_US;
+		} else if (tsf_id == 1) {
+			*tsf_enum_low = PMM_MAC1_TSF2_OFFSET_LO_US;
+			*tsf_enum_hi = PMM_MAC1_TSF2_OFFSET_HI_US;
+		}
+	}
+}
+
+static inline uint32_t
+hal_tsf_read_scratch_reg(struct hal_soc *soc,
+			 enum hal_scratch_reg_enum reg_enum)
+{
+	return hal_read32_mb(soc, PMM_REG_BASE + (reg_enum * 4));
+}
+
+static inline
+uint64_t hal_tsf_get_fw_time(struct hal_soc *soc)
+{
+	uint64_t fw_time_low;
+	uint64_t fw_time_high;
+
+	fw_time_low = hal_read32_mb(soc, PCIE_PCIE_MHI_TIME_LOW);
+	fw_time_high = hal_read32_mb(soc, PCIE_PCIE_MHI_TIME_HIGH);
+	return (fw_time_high << 32 | fw_time_low);
+}
+
+static inline
+uint64_t hal_fw_qtime_to_usecs(uint64_t time)
+{
+	/*
+	 * Try to preserve precision by multiplying by 10 first.
+	 * If that would cause a wrap around, divide first instead.
+	 */
+	if (time * 10 < time) {
+		time = qdf_do_div(time, FW_QTIME_CYCLES_PER_10_USEC);
+		return time * 10;
+	}
+
+	time = time * 10;
+	time = qdf_do_div(time, FW_QTIME_CYCLES_PER_10_USEC);
+
+	return time;
+}
+
+/**
+ * hal_get_tsf_time_kiwi() - Get tsf time from scatch register
+ * @hal_soc_hdl: HAL soc handle
+ * @mac_id: mac_id
+ * @tsf: pointer to update tsf value
+ * @tsf_sync_soc_time: pointer to update tsf sync time
+ *
+ * Return: None.
+ */
+static void
+hal_get_tsf_time_kiwi(hal_soc_handle_t hal_soc_hdl, uint32_t tsf_id,
+		      uint32_t mac_id, uint64_t *tsf,
+		      uint64_t *tsf_sync_soc_time)
+{
+	struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl;
+	uint64_t global_time_low_offset, global_time_high_offset;
+	uint64_t tsf_offset_low, tsf_offset_hi;
+	uint64_t fw_time, global_time, sync_time;
+	enum hal_scratch_reg_enum tsf_enum_low, tsf_enum_high;
+
+	if (hif_force_wake_request(soc->hif_handle))
+		return;
+
+	hal_get_tsf_enum(tsf_id, mac_id, &tsf_enum_low, &tsf_enum_high);
+	sync_time = qdf_get_log_timestamp();
+	fw_time = hal_tsf_get_fw_time(soc);
+
+	global_time_low_offset =
+		hal_tsf_read_scratch_reg(soc, PMM_QTIMER_GLOBAL_OFFSET_LO_US);
+	global_time_high_offset =
+		hal_tsf_read_scratch_reg(soc, PMM_QTIMER_GLOBAL_OFFSET_HI_US);
+
+	tsf_offset_low = hal_tsf_read_scratch_reg(soc, tsf_enum_low);
+	tsf_offset_hi = hal_tsf_read_scratch_reg(soc, tsf_enum_high);
+
+	fw_time = hal_fw_qtime_to_usecs(fw_time);
+	global_time = fw_time +
+		      (global_time_low_offset |
+		      (global_time_high_offset << 32));
+
+	*tsf = global_time + (tsf_offset_low | (tsf_offset_hi << 32));
+	*tsf_sync_soc_time = qdf_log_timestamp_to_usecs(sync_time);
+
+	hif_force_wake_release(soc->hif_handle);
+}
+#else
+static inline void
+hal_get_tsf_time_kiwi(hal_soc_handle_t hal_soc_hdl, uint32_t tsf_id,
+		      uint32_t mac_id, uint64_t *tsf,
+		      uint64_t *tsf_sync_soc_time)
+{
+}
+#endif
+
 static void hal_hw_txrx_ops_attach_kiwi(struct hal_soc *hal_soc)
 {
 	/* init and setup */
@@ -2123,6 +2268,7 @@ static void hal_hw_txrx_ops_attach_kiwi(struct hal_soc *hal_soc)
 		hal_tx_populate_bank_register_be;
 	hal_soc->ops->hal_tx_vdev_mcast_ctrl_set =
 		hal_tx_vdev_mcast_ctrl_set_be;
+	hal_soc->ops->hal_get_tsf_time = hal_get_tsf_time_kiwi;
 };
 
 struct hal_hw_srng_config hw_srng_table_kiwi[] = {