Ver código fonte

Merge "msm: ipa4: Add changes to support PCIe addr for WDI2 over GSI"

qctecmdr 3 anos atrás
pai
commit
506114ab6c

+ 16 - 0
drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c

@@ -498,6 +498,10 @@ static int ipa_wdi_conn_pipes_internal(struct ipa_wdi_conn_in_params *in,
 				in->u_rx.rx.event_ring_doorbell_pa;
 			in_rx.u.ul.rdy_comp_ring_size =
 				in->u_rx.rx.event_ring_size;
+			in_rx.u.ul.is_txr_rn_db_pcie_addr =
+				in->u_rx.rx.is_txr_rn_db_pcie_addr;
+			in_rx.u.ul.is_evt_rn_db_pcie_addr =
+				in->u_rx.rx.is_evt_rn_db_pcie_addr;
 			if (ipa3_connect_wdi_pipe(&in_rx, &out_rx)) {
 				IPA_WDI_ERR("fail to setup rx pipe\n");
 				ret = -EFAULT;
@@ -523,6 +527,10 @@ static int ipa_wdi_conn_pipes_internal(struct ipa_wdi_conn_in_params *in,
 				in->u_tx.tx.event_ring_size;
 			in_tx.u.dl.num_tx_buffers =
 				in->u_tx.tx.num_pkt_buffers;
+			in_tx.u.dl.is_txr_rn_db_pcie_addr =
+				in->u_tx.tx.is_txr_rn_db_pcie_addr;
+			in_tx.u.dl.is_evt_rn_db_pcie_addr =
+				in->u_tx.tx.is_evt_rn_db_pcie_addr;
 			if (ipa3_connect_wdi_pipe(&in_tx, &out_tx)) {
 				IPA_WDI_ERR("fail to setup tx pipe\n");
 				ret = -EFAULT;
@@ -550,6 +558,10 @@ static int ipa_wdi_conn_pipes_internal(struct ipa_wdi_conn_in_params *in,
 				in->u_rx.rx_smmu.event_ring_doorbell_pa;
 			in_rx.u.ul_smmu.rdy_comp_ring_size =
 				in->u_rx.rx_smmu.event_ring_size;
+			in_rx.u.ul_smmu.is_txr_rn_db_pcie_addr =
+				in->u_rx.rx_smmu.is_txr_rn_db_pcie_addr;
+			in_rx.u.ul_smmu.is_evt_rn_db_pcie_addr =
+				in->u_rx.rx_smmu.is_evt_rn_db_pcie_addr;
 			if (ipa3_connect_wdi_pipe(&in_rx, &out_rx)) {
 				IPA_WDI_ERR("fail to setup rx pipe\n");
 				ret = -EFAULT;
@@ -575,6 +587,10 @@ static int ipa_wdi_conn_pipes_internal(struct ipa_wdi_conn_in_params *in,
 				in->u_tx.tx_smmu.event_ring_size;
 			in_tx.u.dl_smmu.num_tx_buffers =
 				in->u_tx.tx_smmu.num_pkt_buffers;
+			in_tx.u.dl_smmu.is_txr_rn_db_pcie_addr =
+				in->u_tx.tx_smmu.is_txr_rn_db_pcie_addr;
+			in_tx.u.dl_smmu.is_evt_rn_db_pcie_addr =
+				in->u_tx.tx_smmu.is_evt_rn_db_pcie_addr;
 			if (ipa3_connect_wdi_pipe(&in_tx, &out_tx)) {
 				IPA_WDI_ERR("fail to setup tx pipe\n");
 				ret = -EFAULT;

+ 149 - 4
drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c

@@ -1206,6 +1206,8 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
 	unsigned long wifi_rx_ri_addr = 0;
 	u32 gsi_db_reg_phs_addr_lsb;
 	u32 gsi_db_reg_phs_addr_msb;
+	uint32_t addr_low, addr_high;
+	bool is_evt_rn_db_pcie_addr, is_txr_rn_db_pcie_addr;
 
 	ipa_ep_idx = ipa3_get_ep_mapping(in->sys.client);
 	if (ipa_ep_idx == -1) {
@@ -1455,6 +1457,97 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
 				&ep->gsi_evt_ring_hdl);
 	if (result)
 		goto fail_alloc_evt_ring;
+
+	is_evt_rn_db_pcie_addr = IPA_CLIENT_IS_CONS(in->sys.client) ?
+		in->u.dl.is_evt_rn_db_pcie_addr :
+		in->u.ul.is_evt_rn_db_pcie_addr;
+
+	if (IPA_CLIENT_IS_CONS(in->sys.client)) {
+		is_evt_rn_db_pcie_addr = in->smmu_enabled ?
+			in->u.dl_smmu.is_evt_rn_db_pcie_addr :
+			in->u.dl.is_evt_rn_db_pcie_addr;
+		gsi_evt_ring_props.rp_update_addr = in->smmu_enabled ?
+			in->u.dl_smmu.ce_door_bell_pa :
+			in->u.dl.ce_door_bell_pa;
+	} else {
+		is_evt_rn_db_pcie_addr = in->smmu_enabled ?
+			in->u.ul_smmu.is_evt_rn_db_pcie_addr :
+			in->u.ul.is_evt_rn_db_pcie_addr;
+		gsi_evt_ring_props.rp_update_addr = in->smmu_enabled ?
+			in->u.ul_smmu.rdy_comp_ring_wp_pa :
+			in->u.ul.rdy_comp_ring_wp_pa;
+	}
+	if (!in->smmu_enabled) {
+		IPADBG("smmu disabled\n");
+		if (is_evt_rn_db_pcie_addr == true)
+			IPADBG("is_evt_rn_db_pcie_addr is PCIE addr\n");
+		else
+			IPADBG("is_evt_rn_db_pcie_addr is DDR addr\n");
+
+		addr_low = (u32)gsi_evt_ring_props.rp_update_addr;
+		addr_high = (u32)((u64)gsi_evt_ring_props.rp_update_addr >> 32);
+	} else {
+		IPADBG("smmu enabled\n");
+		if (is_evt_rn_db_pcie_addr == true)
+			IPADBG("is_evt_rn_db_pcie_addr is PCIE addr\n");
+		else
+			IPADBG("is_evt_rn_db_pcie_addr is DDR addr\n");
+
+		if (IPA_CLIENT_IS_CONS(in->sys.client)) {
+			if (ipa_create_gsi_smmu_mapping(IPA_WDI_CE_DB_RES,
+				true, gsi_evt_ring_props.rp_update_addr,
+				NULL, 4, true, &va)) {
+					IPAERR("failed to get smmu mapping\n");
+					result = -EFAULT;
+					goto fail_alloc_evt_ring;
+			}
+		} else {
+			if (ipa_create_gsi_smmu_mapping(
+				IPA_WDI_RX_COMP_RING_WP_RES,
+				true, gsi_evt_ring_props.rp_update_addr,
+				NULL, 4, true, &va)) {
+				IPAERR("failed to get smmu mapping\n");
+				result = -EFAULT;
+				goto fail_alloc_evt_ring;
+			}
+		}
+		addr_low = (u32)va;
+		addr_high = (u32)((u64)va >> 32);
+	}
+
+	/*
+	* Arch specific:
+	* pcie addr which are not via smmu, use pa directly!
+	* pcie and DDR via 2 different port
+	* assert bit 40 to indicate it is pcie addr
+	* WDI-3.0, MSM --> pcie via smmu
+	* WDI-3.0, MDM --> pcie not via smmu + dual port
+	* assert bit 40 in case
+	*/
+	if (!ipa3_is_msm_device() &&
+		in->smmu_enabled) {
+		/*
+		* Ir-respective of smmu enabled don't use IOVA addr
+		* since pcie not via smmu in MDM's
+		*/
+		if (is_evt_rn_db_pcie_addr == true) {
+			addr_low = (u32)gsi_evt_ring_props.rp_update_addr;
+			addr_high =
+				(u32)((u64)gsi_evt_ring_props.rp_update_addr
+				>> 32);
+		}
+	}
+
+	/*
+	* GSI recomendation to set bit-40 for (mdm targets && pcie addr)
+	* from wdi-3.0 interface document
+	*/
+	if (!ipa3_is_msm_device() && is_evt_rn_db_pcie_addr)
+		addr_high |= (1 << 8);
+
+	gsi_wdi3_write_evt_ring_db(ep->gsi_evt_ring_hdl, addr_low,
+			addr_high);
+
 	/*copy mem info */
 	ep->gsi_mem_info.evt_ring_len = gsi_evt_ring_props.ring_len;
 	ep->gsi_mem_info.evt_ring_base_addr = gsi_evt_ring_props.ring_base_addr;
@@ -1484,10 +1577,62 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
 	IPAERR("UPDATE_RI_MODERATION_THRESHOLD: %d\n", num_ring_ele);
 	if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_7) {
 		if (IPA_CLIENT_IS_PROD(in->sys.client)) {
-			gsi_scratch.wdi.wifi_rx_ri_addr_low =
-				wifi_rx_ri_addr & 0xFFFFFFFF;
-			gsi_scratch.wdi.wifi_rx_ri_addr_high =
-				(wifi_rx_ri_addr & 0xFFFFF00000000) >> 32;
+			is_txr_rn_db_pcie_addr =
+			in->smmu_enabled ?
+				in->u.ul_smmu.is_txr_rn_db_pcie_addr :
+				in->u.ul.is_txr_rn_db_pcie_addr;
+			if (!in->smmu_enabled) {
+				IPADBG("smmu disabled\n");
+				gsi_scratch.wdi2_new.wifi_rx_ri_addr_low =
+					in->u.ul.rdy_ring_rp_pa & 0xFFFFFFFF;
+				gsi_scratch.wdi2_new.wifi_rx_ri_addr_high =
+					(in->u.ul.rdy_ring_rp_pa &
+						0xFFFFF00000000) >> 32;
+			} else {
+				IPADBG("smmu eabled\n");
+				gsi_scratch.wdi.wifi_rx_ri_addr_low =
+					wifi_rx_ri_addr & 0xFFFFFFFF;
+				gsi_scratch.wdi.wifi_rx_ri_addr_high =
+					(wifi_rx_ri_addr & 0xFFFFF00000000) >> 32;
+			}
+
+			/*
+			* Arch specific:
+			* pcie addr which are not via smmu, use pa directly!
+			* pcie and DDR via 2 different port
+			* assert bit 40 to indicate it is pcie addr
+			* WDI-3.0, MSM --> pcie via smmu
+			* WDI-3.0, MDM --> pcie not via smmu + dual port
+			* assert bit 40 in case
+			*/
+			if (!ipa3_is_msm_device() &&
+					in->smmu_enabled) {
+				/*
+				* Ir-respective of smmu enabled don't use IOVA
+				* addr since pcie not via smmu in MDM's
+				*/
+				if (is_txr_rn_db_pcie_addr == true) {
+					gsi_scratch.wdi2_new.wifi_rx_ri_addr_low
+						= in->u.ul_smmu.rdy_ring_rp_pa
+							& 0xFFFFFFFF;
+				gsi_scratch.wdi2_new.wifi_rx_ri_addr_high =
+					(in->u.ul_smmu.rdy_ring_rp_pa &
+						0xFFFFF00000000) >> 32;
+				}
+			}
+
+			/*
+			 * GSI recomendation to set bit-40 for
+			 * (mdm targets && pcie addr) from wdi-3.0
+			 * interface document
+			*/
+
+			if (!ipa3_is_msm_device() && is_txr_rn_db_pcie_addr)
+				gsi_scratch.wdi2_new.wifi_rx_ri_addr_high =
+				(u32)((u32)
+				gsi_scratch.wdi2_new.wifi_rx_ri_addr_high |
+				(1 << 8));
+
 			gsi_scratch.wdi.wdi_rx_vdev_id = 0xff;
 			gsi_scratch.wdi.wdi_rx_fw_desc = 0xff;
 			gsi_scratch.wdi.endp_metadatareg_offset =