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

Add changes to support PCIe addr for WDI2 over GSI

Change-Id: I9084e735b5eb4a75cefc2daeaa22340a5014b2b4
Signed-off-by: Pooja Kumari <kumarip@codeaurora.org>
Signed-off-by: Ashok Vuyyuru <avuyyuru@codeaurora.org>
tirimbino
Ashok Vuyyuru 5 years ago committed by Gerrit - the friendly Code Review server
parent b5ff61877b
commit 4864c2459c
  1. 16
      drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c
  2. 159
      drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
  3. 18
      include/linux/ipa.h

@ -558,6 +558,10 @@ int ipa_wdi_conn_pipes(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 (ipa_connect_wdi_pipe(&in_rx, &out_rx)) {
IPA_WDI_ERR("fail to setup rx pipe\n");
ret = -EFAULT;
@ -583,6 +587,10 @@ int ipa_wdi_conn_pipes(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 (ipa_connect_wdi_pipe(&in_tx, &out_tx)) {
IPA_WDI_ERR("fail to setup tx pipe\n");
ret = -EFAULT;
@ -610,6 +618,10 @@ int ipa_wdi_conn_pipes(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 (ipa_connect_wdi_pipe(&in_rx, &out_rx)) {
IPA_WDI_ERR("fail to setup rx pipe\n");
ret = -EFAULT;
@ -635,6 +647,10 @@ int ipa_wdi_conn_pipes(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 (ipa_connect_wdi_pipe(&in_tx, &out_tx)) {
IPA_WDI_ERR("fail to setup tx pipe\n");
ret = -EFAULT;

@ -1184,6 +1184,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) {
@ -1439,6 +1441,99 @@ 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;
@ -1479,14 +1574,70 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
gsi_scratch.wdi.wdi_rx_tre_proc_in_progress = 0;
} else {
if (IPA_CLIENT_IS_PROD(in->sys.client)) {
gsi_scratch.wdi2_new.wifi_rx_ri_addr_low =
wifi_rx_ri_addr & 0xFFFFFFFF;
gsi_scratch.wdi2_new.wifi_rx_ri_addr_high =
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.wdi2_new.wifi_rx_ri_addr_low =
wifi_rx_ri_addr & 0xFFFFFFFF;
gsi_scratch.wdi2_new.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.wdi2_new.wdi_rx_vdev_id = 0xff;
gsi_scratch.wdi2_new.wdi_rx_fw_desc = 0xff;
gsi_scratch.wdi2_new.endp_metadatareg_offset =
ipahal_get_reg_mn_ofst(
ipahal_get_reg_mn_ofst(
IPA_ENDP_INIT_HDR_METADATA_n, 0,
ipa_ep_idx)/4;
gsi_scratch.wdi2_new.qmap_id = 0;

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -1051,6 +1051,8 @@ struct IpaHwStatsWDIInfoData_t {
* uc is writing (WDI-2.0)
* @rdy_comp_ring_size: size of the Rx_completion ring in bytes
* expected to communicate about the Read pointer into the Rx Ring
* @is_txr_rn_db_pcie_addr: tx ring PCIE doorbell address
* @is_evt_rn_db_pcie_addr: event ring PCIE doorbell address
*/
struct ipa_wdi_ul_params {
phys_addr_t rdy_ring_base_pa;
@ -1061,6 +1063,8 @@ struct ipa_wdi_ul_params {
u32 rdy_comp_ring_size;
u32 *rdy_ring_rp_va;
u32 *rdy_comp_ring_wp_va;
bool is_txr_rn_db_pcie_addr;
bool is_evt_rn_db_pcie_addr;
};
/**
@ -1069,6 +1073,8 @@ struct ipa_wdi_ul_params {
* @rdy_ring_size: size of the Rx ring in bytes
* @rdy_ring_rp_pa: physical address of the location through which IPA uc is
* expected to communicate about the Read pointer into the Rx Ring
* @is_txr_rn_db_pcie_addr: tx ring PCIE doorbell address
* @is_evt_rn_db_pcie_addr: event ring PCIE doorbell address
*/
struct ipa_wdi_ul_params_smmu {
struct sg_table rdy_ring;
@ -1079,6 +1085,8 @@ struct ipa_wdi_ul_params_smmu {
u32 rdy_comp_ring_size;
u32 *rdy_ring_rp_va;
u32 *rdy_comp_ring_wp_va;
bool is_txr_rn_db_pcie_addr;
bool is_evt_rn_db_pcie_addr;
};
/**
@ -1091,6 +1099,8 @@ struct ipa_wdi_ul_params_smmu {
* write into to trigger the copy engine
* @ce_ring_size: Copy Engine Ring size in bytes
* @num_tx_buffers: Number of pkt buffers allocated
* @is_txr_rn_db_pcie_addr: tx ring PCIE doorbell address
* @is_evt_rn_db_pcie_addr: event ring PCIE doorbell address
*/
struct ipa_wdi_dl_params {
phys_addr_t comp_ring_base_pa;
@ -1099,6 +1109,8 @@ struct ipa_wdi_dl_params {
phys_addr_t ce_door_bell_pa;
u32 ce_ring_size;
u32 num_tx_buffers;
bool is_txr_rn_db_pcie_addr;
bool is_evt_rn_db_pcie_addr;
};
/**
@ -1110,6 +1122,8 @@ struct ipa_wdi_dl_params {
* write into to trigger the copy engine
* @ce_ring_size: Copy Engine Ring size in bytes
* @num_tx_buffers: Number of pkt buffers allocated
* @is_txr_rn_db_pcie_addr: tx ring PCIE doorbell address
* @is_evt_rn_db_pcie_addr: event ring PCIE doorbell address
*/
struct ipa_wdi_dl_params_smmu {
struct sg_table comp_ring;
@ -1118,6 +1132,8 @@ struct ipa_wdi_dl_params_smmu {
phys_addr_t ce_door_bell_pa;
u32 ce_ring_size;
u32 num_tx_buffers;
bool is_txr_rn_db_pcie_addr;
bool is_evt_rn_db_pcie_addr;
};
/**

Loading…
Cancel
Save