Commit b42b3678 authored by Sriram R's avatar Sriram R Committed by Kalle Valo
Browse files

wifi: ath11k: remap ce register space for IPQ5018



In IPQ5018 ce register space is moved out of wcss unlike
ipq8074 or ipq6018 and the space is not contiguous,
hence remap the CE registers to a new space to access them.

Register read/write is modified to check if the register to be written
falls in the CE register space and corresponding register is written.
Also adjust the interrupt register address to ce irq enable/disable.

Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1

Signed-off-by: default avatarSriram R <quic_srirrama@quicinc.com>
Co-developed-by: default avatarKarthikeyan Kathirvel <quic_kathirve@quicinc.com>
Signed-off-by: default avatarKarthikeyan Kathirvel <quic_kathirve@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20221122132152.17771-5-quic_kathirve@quicinc.com
parent 26af7aab
Loading
Loading
Loading
Loading
+38 −6
Original line number Diff line number Diff line
@@ -267,30 +267,42 @@ static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset)
static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
{
	const struct ce_attr *ce_attr;
	const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
	u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;

	ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
	ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
	ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);

	ce_attr = &ab->hw_params.host_ce_config[ce_id];
	if (ce_attr->src_nentries)
		ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
		ath11k_ahb_setbit32(ab, ce_id, ie1_reg_addr);

	if (ce_attr->dest_nentries) {
		ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
		ath11k_ahb_setbit32(ab, ce_id, ie2_reg_addr);
		ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
				    CE_HOST_IE_3_ADDRESS);
				    ie3_reg_addr);
	}
}

static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
{
	const struct ce_attr *ce_attr;
	const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
	u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;

	ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
	ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
	ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);

	ce_attr = &ab->hw_params.host_ce_config[ce_id];
	if (ce_attr->src_nentries)
		ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
		ath11k_ahb_clearbit32(ab, ce_id, ie1_reg_addr);

	if (ce_attr->dest_nentries) {
		ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
		ath11k_ahb_clearbit32(ab, ce_id, ie2_reg_addr);
		ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
				      CE_HOST_IE_3_ADDRESS);
				      ie3_reg_addr);
	}
}

@@ -1142,10 +1154,26 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
		goto err_core_free;
	}

	ab->mem_ce = ab->mem;

	ret = ath11k_core_pre_init(ab);
	if (ret)
		goto err_core_free;

	if (ab->hw_params.ce_remap) {
		const struct ce_remap *ce_remap = ab->hw_params.ce_remap;
		/* ce register space is moved out of wcss unlike ipq8074 or ipq6018
		 * and the space is not contiguous, hence remapping the CE registers
		 * to a new space for accessing them.
		 */
		ab->mem_ce = ioremap(ce_remap->base, ce_remap->size);
		if (IS_ERR(ab->mem_ce)) {
			dev_err(&pdev->dev, "ce ioremap error\n");
			ret = -ENOMEM;
			goto err_core_free;
		}
	}

	ret = ath11k_ahb_setup_resources(ab);
	if (ret)
		goto err_core_free;
@@ -1236,6 +1264,10 @@ static void ath11k_ahb_free_resources(struct ath11k_base *ab)
	ath11k_ahb_release_smp2p_handle(ab);
	ath11k_ahb_fw_resource_deinit(ab);
	ath11k_ce_free_pipes(ab);

	if (ab->hw_params.ce_remap)
		iounmap(ab->mem_ce);

	ath11k_core_free(ab);
	platform_set_drvdata(pdev, NULL);
}
+16 −0
Original line number Diff line number Diff line
@@ -49,6 +49,11 @@ void ath11k_ce_byte_swap(void *mem, u32 len);
#define CE_HOST_IE_2_ADDRESS	0x00A18040
#define CE_HOST_IE_3_ADDRESS	CE_HOST_IE_ADDRESS

/* CE IE registers are different for IPQ5018 */
#define CE_HOST_IPQ5018_IE_ADDRESS		0x0841804C
#define CE_HOST_IPQ5018_IE_2_ADDRESS		0x08418050
#define CE_HOST_IPQ5018_IE_3_ADDRESS		CE_HOST_IPQ5018_IE_ADDRESS

#define CE_HOST_IE_3_SHIFT	0xC

#define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
@@ -84,6 +89,17 @@ struct ce_pipe_config {
	__le32 reserved;
};

struct ce_ie_addr {
	u32 ie1_reg_addr;
	u32 ie2_reg_addr;
	u32 ie3_reg_addr;
};

struct ce_remap {
	u32 base;
	u32 size;
};

struct ce_attr {
	/* CE_ATTR_* values */
	unsigned int flags;
+8 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.target_ce_count = 11,
		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
		.svc_to_ce_map_len = 21,
		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
		.single_pdev_only = false,
		.rxdma1_enable = true,
		.num_rxmda_per_pdev = 1,
@@ -137,6 +138,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.target_ce_count = 11,
		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
		.svc_to_ce_map_len = 19,
		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
		.single_pdev_only = false,
		.rxdma1_enable = true,
		.num_rxmda_per_pdev = 1,
@@ -218,6 +220,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.target_ce_count = 9,
		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
		.svc_to_ce_map_len = 14,
		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
		.single_pdev_only = true,
		.rxdma1_enable = false,
		.num_rxmda_per_pdev = 2,
@@ -301,6 +304,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.target_ce_count = 9,
		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
		.svc_to_ce_map_len = 18,
		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
		.rxdma1_enable = true,
		.num_rxmda_per_pdev = 1,
		.rx_mac_buf_ring = false,
@@ -381,6 +385,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.target_ce_count = 9,
		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
		.svc_to_ce_map_len = 14,
		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
		.single_pdev_only = true,
		.rxdma1_enable = false,
		.num_rxmda_per_pdev = 2,
@@ -546,6 +551,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.target_ce_count = 9,
		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
		.svc_to_ce_map_len = 14,
		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
		.single_pdev_only = true,
		.rxdma1_enable = false,
		.num_rxmda_per_pdev = 1,
@@ -634,6 +640,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.target_ce_count = TARGET_CE_CNT_5018,
		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018,
		.svc_to_ce_map_len = SVC_CE_MAP_LEN_5018,
		.ce_ie_addr = &ath11k_ce_ie_addr_ipq5018,
		.ce_remap = &ath11k_ce_remap_ipq5018,
		.rxdma1_enable = true,
		.num_rxmda_per_pdev = RXDMA_PER_PDEV_5018,
		.rx_mac_buf_ring = false,
+1 −0
Original line number Diff line number Diff line
@@ -851,6 +851,7 @@ struct ath11k_base {
	struct ath11k_dp dp;

	void __iomem *mem;
	void __iomem *mem_ce;
	unsigned long mem_len;

	struct {
+11 −6
Original line number Diff line number Diff line
@@ -1220,16 +1220,20 @@ static int ath11k_hal_srng_create_config(struct ath11k_base *ab)
	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;

	s = &hal->srng_config[HAL_CE_SRC];
	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP;
	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
		ATH11K_CE_OFFSET(ab);
	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP +
		ATH11K_CE_OFFSET(ab);
	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
		HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
		HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);

	s = &hal->srng_config[HAL_CE_DST];
	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP;
	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
		ATH11K_CE_OFFSET(ab);
	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP +
		ATH11K_CE_OFFSET(ab);
	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
		HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
@@ -1237,8 +1241,9 @@ static int ath11k_hal_srng_create_config(struct ath11k_base *ab)

	s = &hal->srng_config[HAL_CE_DST_STATUS];
	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) +
		HAL_CE_DST_STATUS_RING_BASE_LSB;
	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP;
		HAL_CE_DST_STATUS_RING_BASE_LSB + ATH11K_CE_OFFSET(ab);
	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP +
		ATH11K_CE_OFFSET(ab);
	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
		HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
Loading