Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38193f52 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ath10k: Enable SRRI/DRRI support on ddr"

parents 1e3e2c07 6c041646
Loading
Loading
Loading
Loading
+76 −3
Original line number Diff line number Diff line
@@ -96,13 +96,29 @@ static inline u32 ath10k_ce_src_ring_write_index_get(struct ath10k *ar,
			ce_ctrl_addr + ar->hw_ce_regs->sr_wr_index_addr);
}

static inline u32 ath10k_ce_src_ring_read_index_get_from_ddr(
				struct ath10k *ar, u32 ce_id)
{
	struct bus_opaque *ar_opaque = ath10k_bus_priv(ar);

	return ar_opaque->vaddr_rri_on_ddr[ce_id] & CE_DDR_RRI_MASK;
}

static inline u32 ath10k_ce_src_ring_read_index_get(struct ath10k *ar,
						    u32 ce_ctrl_addr)
{
	struct bus_opaque *ar_opaque = ath10k_bus_priv(ar);
	u32 ce_id = COPY_ENGINE_ID(ce_ctrl_addr);
	struct ath10k_ce_pipe *ce_state = &ar_opaque->ce_states[ce_id];
	u32 index;

	return ar_opaque->bus_ops->read32(ar,
	if (ar->rri_on_ddr && (ce_state->attr_flags & CE_ATTR_DIS_INTR))
		index = ath10k_ce_src_ring_read_index_get_from_ddr(ar, ce_id);
	else
		index = ar_opaque->bus_ops->read32(ar,
			ce_ctrl_addr + ar->hw_ce_regs->current_srri_addr);

	return index;
}

static inline void ath10k_ce_shadow_src_ring_write_index_set(struct ath10k *ar,
@@ -195,9 +211,19 @@ static inline u32 ath10k_ce_dest_ring_read_index_get(struct ath10k *ar,
						     u32 ce_ctrl_addr)
{
	struct bus_opaque *ar_opaque = ath10k_bus_priv(ar);
	u32 ce_id = COPY_ENGINE_ID(ce_ctrl_addr);
	struct ath10k_ce_pipe *ce_state = &ar_opaque->ce_states[ce_id];
	u32 index;

	return ar_opaque->bus_ops->read32(ar,
	if (ar->rri_on_ddr && (ce_state->attr_flags & CE_ATTR_DIS_INTR))
		index = (ar_opaque->vaddr_rri_on_ddr[ce_id] >>
			  CE_DDR_RRI_SHIFT) &
			  CE_DDR_RRI_MASK;
	else
		index = ar_opaque->bus_ops->read32(ar,
			ce_ctrl_addr + ar->hw_ce_regs->current_drri_addr);

	return index;
}

static inline void ath10k_ce_dest_ring_base_addr_set(struct ath10k *ar,
@@ -449,7 +475,7 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
	struct ath10k_ce_ring *src_ring = ce_state->src_ring;
	struct ce_desc *desc, sdesc;
	unsigned int nentries_mask = src_ring->nentries_mask;
	unsigned int sw_index = src_ring->sw_index;
	unsigned int sw_index;
	unsigned int write_index = src_ring->write_index;
	u32 ctrl_addr = ce_state->ctrl_addr;
	u32 desc_flags = 0;
@@ -462,6 +488,7 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
		ath10k_warn(ar, "%s: send more we can (nbytes: %d, max: %d)\n",
			    __func__, nbytes, ce_state->src_sz_max);

	sw_index = ath10k_ce_src_ring_read_index_get_from_ddr(ar, ce_state->id);
	if (unlikely(CE_RING_DELTA(nentries_mask,
				   write_index, sw_index - 1) <= 0)) {
		ret = -ENOSR;
@@ -1235,6 +1262,52 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
	return dest_ring;
}

void ce_config_rri_on_ddr(struct ath10k *ar)
{
	struct bus_opaque *ar_opaque = ath10k_bus_priv(ar);
	u32 hi_paddr, low_paddr;
	u32 ce_base_addr;
	u32 ctrl1_regs;
	int i;

	ar_opaque->vaddr_rri_on_ddr =
		(u32 *)dma_alloc_coherent(ar->dev,
		(CE_COUNT * sizeof(u32)),
		&ar_opaque->paddr_rri_on_ddr, GFP_KERNEL);

	if (!ar_opaque->vaddr_rri_on_ddr)
		return;

	low_paddr  = lower_32_bits(ar_opaque->paddr_rri_on_ddr);
	hi_paddr = upper_32_bits(ar_opaque->paddr_rri_on_ddr) &
					CE_DESC_FLAGS_GET_MASK;

	ar_opaque->bus_ops->write32(ar, ar->hw_ce_regs->ce_rri_low, low_paddr);
	ar_opaque->bus_ops->write32(ar, ar->hw_ce_regs->ce_rri_high, hi_paddr);

	for (i = 0; i < CE_COUNT; i++) {
		ctrl1_regs = ar->hw_ce_regs->ctrl1_regs->addr;
		ce_base_addr = ath10k_ce_base_address(ar, i);
		ar_opaque->bus_ops->write32(ar, ce_base_addr + ctrl1_regs,
		ar_opaque->bus_ops->read32(ar, ce_base_addr + ctrl1_regs) |
		ar->hw_ce_regs->upd->mask);
	}

	memset(ar_opaque->vaddr_rri_on_ddr, 0, CE_COUNT * sizeof(u32));
}

void ce_remove_rri_on_ddr(struct ath10k *ar)
{
	struct bus_opaque *ar_opaque = ath10k_bus_priv(ar);

	if (!ar_opaque->vaddr_rri_on_ddr)
		return;

	dma_free_coherent(ar->dev, (CE_COUNT * sizeof(u32)),
			  ar_opaque->vaddr_rri_on_ddr,
			  ar_opaque->paddr_rri_on_ddr);
}

/*
 * Initialize a Copy Engine based on caller-supplied attributes.
 * This may be called once to initialize both source and destination
+6 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ struct ath10k_ce_pipe;

#define CE_DESC_FLAGS_GET_MASK		0x1F
#define CE_DESC_37BIT_ADDR_MASK		0x1FFFFFFFFF
#define CE_DDR_RRI_MASK			0xFFFF
#define CE_DDR_RRI_SHIFT		16

/* Following desc flags are used in QCA99X0 */
#define CE_DESC_FLAGS_HOST_INT_DIS	(1 << 2)
@@ -211,6 +213,8 @@ struct bus_opaque {
	spinlock_t ce_lock;
	const struct ath10k_bus_ops *bus_ops;
	struct ath10k_ce_pipe ce_states[CE_COUNT_MAX];
	u32 *vaddr_rri_on_ddr;
	dma_addr_t paddr_rri_on_ddr;
};

/*==================Send====================*/
@@ -288,6 +292,8 @@ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
			 const struct ce_attr *attr);
void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);
void ce_config_rri_on_ddr(struct ath10k *ar);
void ce_remove_rri_on_ddr(struct ath10k *ar);

/*==================CE Engine Shutdown=======================*/
/*
+1 −0
Original line number Diff line number Diff line
@@ -2374,6 +2374,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
		ar->fw_flags = &wcn3990_fw_flags;
		ar->shadow_reg_value = &wcn3990_shadow_reg_value;
		ar->shadow_reg_address = &wcn3990_shadow_reg_address;
		ar->rri_on_ddr = true;
		break;
	default:
		ath10k_err(ar, "unsupported core hardware revision %d\n",
+1 −0
Original line number Diff line number Diff line
@@ -967,6 +967,7 @@ struct ath10k {
	struct completion peer_delete_done;
	bool is_bmi;
	enum ieee80211_sta_state sta_state;
	bool rri_on_ddr;
	/* must be last */
	u8 drv_priv[0] __aligned(sizeof(void *));
};
+7 −0
Original line number Diff line number Diff line
@@ -284,6 +284,12 @@ struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_dst_ring = {
	.wm_high	= &wcn3990_dst_wm_high,
};

static struct ath10k_hw_ce_ctrl1_upd wcn3990_ctrl1_upd = {
	.shift = 19,
	.mask = 0x00080000,
	.enable = 0x00000000,
};

struct ath10k_hw_ce_regs wcn3990_ce_regs = {
	.sr_base_addr		= 0x00000000,
	.sr_size_addr		= 0x00000008,
@@ -305,6 +311,7 @@ struct ath10k_hw_ce_regs wcn3990_ce_regs = {
	.misc_regs		= &wcn3990_misc_reg,
	.wm_srcr		= &wcn3990_wm_src_ring,
	.wm_dstr		= &wcn3990_wm_dst_ring,
	.upd			= &wcn3990_ctrl1_upd,
};

struct ath10k_hw_ce_regs_addr_map qcax_src_ring = {
Loading