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

Commit 27ae5ec6 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Promotion of kernel.lnx.4.4-170219.1.

CRs      Change ID                                   Subject
--------------------------------------------------------------------------------------------------------------
2005599   I78b9f2cadb8c35ab455f4514c7efc9cee4cf4542   msm: ipa: Do not assert if IPA FW loading fails
2008518   Ie90ff74984021fa47070e08b2fc53ad5da46cf35   ath10k: Add support for shadow register for WNC3990

Change-Id: I66bf851a16360275a6282193751a07dec8a9474e
CRs-Fixed: 2005599, 2008518
parents c8466c63 5a092dc8
Loading
Loading
Loading
Loading
+108 −3
Original line number Diff line number Diff line
/*
 * Copyright (c) 2005-2011 Atheros Communications Inc.
 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
 * Copyright (c) 2011-2013, 2017 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -90,6 +90,20 @@ static inline u32 ath10k_ce_src_ring_read_index_get(struct ath10k *ar,
	return ar->bus_read32(ar, ce_ctrl_addr + CURRENT_SRRI_ADDRESS);
}

static inline void ath10k_ce_shadow_src_ring_write_index_set(struct ath10k *ar,
							     u32 ce_ctrl_addr,
							     unsigned int n)
{
	ar->bus_write32(ar, shadow_sr_wr_ind_addr(ar, ce_ctrl_addr), n);
}

static inline void ath10k_ce_shadow_dest_ring_write_index_set(struct ath10k *ar,
							      u32 ce_ctrl_addr,
							      unsigned int n)
{
	ar->bus_write32(ar, shadow_dst_wr_ind_addr(ar, ce_ctrl_addr), n);
}

static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar,
						    u32 ce_ctrl_addr,
						    unsigned int addr)
@@ -259,6 +273,72 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
	ar->bus_write32(ar, ce_ctrl_addr + HOST_IS_ADDRESS, mask);
}

u32 shadow_sr_wr_ind_addr(struct ath10k *ar, u32 ctrl_addr)
{
	u32 addr = 0;
	u32 ce = COPY_ENGINE_ID(ctrl_addr);

	switch (ce) {
	case 0:
		addr = SHADOW_VALUE0;
		break;
	case 3:
		addr = SHADOW_VALUE3;
		break;
	case 4:
		addr = SHADOW_VALUE4;
		break;
	case 5:
		addr = SHADOW_VALUE5;
		break;
	case 7:
		addr = SHADOW_VALUE7;
		break;
	default:
		ath10k_err(ar, "invalid CE ctrl_addr (CE=%d)", ce);
		WARN_ON(1);
	}
	return addr;
}

u32 shadow_dst_wr_ind_addr(struct ath10k *ar, u32 ctrl_addr)
{
	u32 addr = 0;
	u32 ce = COPY_ENGINE_ID(ctrl_addr);

	switch (ce) {
	case 1:
		addr = SHADOW_VALUE13;
		break;
	case 2:
		addr = SHADOW_VALUE14;
		break;
	case 5:
		addr = SHADOW_VALUE17;
		break;
	case 7:
		addr = SHADOW_VALUE19;
		break;
	case 8:
		addr = SHADOW_VALUE20;
		break;
	case 9:
		addr = SHADOW_VALUE21;
		break;
	case 10:
		addr = SHADOW_VALUE22;
		break;
	case 11:
		addr = SHADOW_VALUE23;
		break;
	default:
		ath10k_err(ar, "invalid CE ctrl_addr (CE=%d)", ce);
		WARN_ON(1);
	}

	return addr;
}

/*
 * Guts of ath10k_ce_send, used by both ath10k_ce_send and
 * ath10k_ce_sendlist_send.
@@ -325,8 +405,14 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
	write_index = CE_RING_IDX_INCR(nentries_mask, write_index);

	/* WORKAROUND */
	if (!(flags & CE_SEND_FLAG_GATHER))
		ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, write_index);
	if (!(flags & CE_SEND_FLAG_GATHER)) {
		if (QCA_REV_WCN3990(ar))
			ath10k_ce_shadow_src_ring_write_index_set(ar, ctrl_addr,
								  write_index);
		else
			ath10k_ce_src_ring_write_index_set(ar, ctrl_addr,
							   write_index);
	}

	src_ring->write_index = write_index;
exit:
@@ -957,6 +1043,24 @@ ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id,
			src_ring->base_addr_ce_space_unaligned,
			CE_DESC_RING_ALIGN);

	src_ring->shadow_base_unaligned = kzalloc(
					  nentries * sizeof(struct ce_desc),
					  GFP_KERNEL);

	if (!src_ring->shadow_base_unaligned) {
		dma_free_coherent(ar->dev,
				  (nentries * sizeof(struct ce_desc) +
				   CE_DESC_RING_ALIGN),
				   src_ring->base_addr_owner_space_unaligned,
				   base_addr);
		kfree(src_ring);
		return ERR_PTR(-ENOMEM);
	}

	src_ring->shadow_base = (struct ce_desc *)PTR_ALIGN(
				src_ring->shadow_base_unaligned,
				CE_DESC_RING_ALIGN);

	return src_ring;
}

@@ -1135,6 +1239,7 @@ void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
			((struct ath10k_ce_pipe *)ar->ce_states + ce_id);

	if (ce_state->src_ring) {
		kfree(ce_state->src_ring->shadow_base_unaligned);
		dma_free_coherent(ar->dev,
				  (ce_state->src_ring->nentries *
				   sizeof(struct ce_desc) +
+61 −0
Original line number Diff line number Diff line
@@ -120,6 +120,9 @@ struct ath10k_ce_ring {
	/* CE address space */
	u32 base_addr_ce_space;

	char *shadow_base_unaligned;
	struct ce_desc *shadow_base;

	/* keep last */
	void *per_transfer_context[0];
};
@@ -143,6 +146,61 @@ struct ath10k_ce_pipe {
/* Copy Engine settable attributes */
struct ce_attr;

#define SHADOW_VALUE0       (ar->shadow_reg_value->shadow_reg_value_0)
#define SHADOW_VALUE1       (ar->shadow_reg_value->shadow_reg_value_1)
#define SHADOW_VALUE2       (ar->shadow_reg_value->shadow_reg_value_2)
#define SHADOW_VALUE3       (ar->shadow_reg_value->shadow_reg_value_3)
#define SHADOW_VALUE4       (ar->shadow_reg_value->shadow_reg_value_4)
#define SHADOW_VALUE5       (ar->shadow_reg_value->shadow_reg_value_5)
#define SHADOW_VALUE6       (ar->shadow_reg_value->shadow_reg_value_6)
#define SHADOW_VALUE7       (ar->shadow_reg_value->shadow_reg_value_7)
#define SHADOW_VALUE8       (ar->shadow_reg_value->shadow_reg_value_8)
#define SHADOW_VALUE9       (ar->shadow_reg_value->shadow_reg_value_9)
#define SHADOW_VALUE10      (ar->shadow_reg_value->shadow_reg_value_10)
#define SHADOW_VALUE11      (ar->shadow_reg_value->shadow_reg_value_11)
#define SHADOW_VALUE12      (ar->shadow_reg_value->shadow_reg_value_12)
#define SHADOW_VALUE13      (ar->shadow_reg_value->shadow_reg_value_13)
#define SHADOW_VALUE14      (ar->shadow_reg_value->shadow_reg_value_14)
#define SHADOW_VALUE15      (ar->shadow_reg_value->shadow_reg_value_15)
#define SHADOW_VALUE16      (ar->shadow_reg_value->shadow_reg_value_16)
#define SHADOW_VALUE17      (ar->shadow_reg_value->shadow_reg_value_17)
#define SHADOW_VALUE18      (ar->shadow_reg_value->shadow_reg_value_18)
#define SHADOW_VALUE19      (ar->shadow_reg_value->shadow_reg_value_19)
#define SHADOW_VALUE20      (ar->shadow_reg_value->shadow_reg_value_20)
#define SHADOW_VALUE21      (ar->shadow_reg_value->shadow_reg_value_21)
#define SHADOW_VALUE22      (ar->shadow_reg_value->shadow_reg_value_22)
#define SHADOW_VALUE23      (ar->shadow_reg_value->shadow_reg_value_23)
#define SHADOW_ADDRESS0     (ar->shadow_reg_address->shadow_reg_address_0)
#define SHADOW_ADDRESS1     (ar->shadow_reg_address->shadow_reg_address_1)
#define SHADOW_ADDRESS2     (ar->shadow_reg_address->shadow_reg_address_2)
#define SHADOW_ADDRESS3     (ar->shadow_reg_address->shadow_reg_address_3)
#define SHADOW_ADDRESS4     (ar->shadow_reg_address->shadow_reg_address_4)
#define SHADOW_ADDRESS5     (ar->shadow_reg_address->shadow_reg_address_5)
#define SHADOW_ADDRESS6     (ar->shadow_reg_address->shadow_reg_address_6)
#define SHADOW_ADDRESS7     (ar->shadow_reg_address->shadow_reg_address_7)
#define SHADOW_ADDRESS8     (ar->shadow_reg_address->shadow_reg_address_8)
#define SHADOW_ADDRESS9     (ar->shadow_reg_address->shadow_reg_address_9)
#define SHADOW_ADDRESS10    (ar->shadow_reg_address->shadow_reg_address_10)
#define SHADOW_ADDRESS11    (ar->shadow_reg_address->shadow_reg_address_11)
#define SHADOW_ADDRESS12    (ar->shadow_reg_address->shadow_reg_address_12)
#define SHADOW_ADDRESS13    (ar->shadow_reg_address->shadow_reg_address_13)
#define SHADOW_ADDRESS14    (ar->shadow_reg_address->shadow_reg_address_14)
#define SHADOW_ADDRESS15    (ar->shadow_reg_address->shadow_reg_address_15)
#define SHADOW_ADDRESS16    (ar->shadow_reg_address->shadow_reg_address_16)
#define SHADOW_ADDRESS17    (ar->shadow_reg_address->shadow_reg_address_17)
#define SHADOW_ADDRESS18    (ar->shadow_reg_address->shadow_reg_address_18)
#define SHADOW_ADDRESS19    (ar->shadow_reg_address->shadow_reg_address_19)
#define SHADOW_ADDRESS20    (ar->shadow_reg_address->shadow_reg_address_20)
#define SHADOW_ADDRESS21    (ar->shadow_reg_address->shadow_reg_address_21)
#define SHADOW_ADDRESS22    (ar->shadow_reg_address->shadow_reg_address_22)
#define SHADOW_ADDRESS23    (ar->shadow_reg_address->shadow_reg_address_23)

#define SHADOW_ADDRESS(i) (SHADOW_ADDRESS0 + \
			   i * (SHADOW_ADDRESS1 - SHADOW_ADDRESS0))

u32 shadow_sr_wr_ind_addr(struct ath10k *ar, u32 ctrl_addr);
u32 shadow_dst_wr_ind_addr(struct ath10k *ar, u32 ctrl_addr);

/*==================Send====================*/

/* ath10k_ce_send flags */
@@ -591,6 +649,9 @@ struct ce_attr {
				     & (uint64_t)(0xF00000000)) >> 32))
#endif

#define COPY_ENGINE_ID(COPY_ENGINE_BASE_ADDRESS) ((COPY_ENGINE_BASE_ADDRESS \
		- CE0_BASE_ADDRESS) / (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS))

static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id)
{
	return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id;
+2 −0
Original line number Diff line number Diff line
@@ -2350,6 +2350,8 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
		/* WCN3990 chip set is non bmi based */
		ar->is_bmi = false;
		ar->fw_flags = &wcn3990_fw_flags;
		ar->shadow_reg_value = &wcn3990_shadow_reg_value;
		ar->shadow_reg_address = &wcn3990_shadow_reg_address;
		break;
	default:
		ath10k_err(ar, "unsupported core hardware revision %d\n",
+2 −0
Original line number Diff line number Diff line
@@ -741,6 +741,8 @@ struct ath10k {

	const struct ath10k_hw_regs *regs;
	const struct ath10k_hw_values *hw_values;
	struct ath10k_shadow_reg_value *shadow_reg_value;
	struct ath10k_shadow_reg_address *shadow_reg_address;
	struct ath10k_bmi bmi;
	struct ath10k_wmi wmi;
	struct ath10k_htc htc;
+54 −0
Original line number Diff line number Diff line
@@ -220,6 +220,60 @@ struct fw_flag wcn3990_fw_flags = {
	.flags = 0x82E,
};

struct ath10k_shadow_reg_value wcn3990_shadow_reg_value = {
	.shadow_reg_value_0  = 0x00032000,
	.shadow_reg_value_1  = 0x00032004,
	.shadow_reg_value_2  = 0x00032008,
	.shadow_reg_value_3  = 0x0003200C,
	.shadow_reg_value_4  = 0x00032010,
	.shadow_reg_value_5  = 0x00032014,
	.shadow_reg_value_6  = 0x00032018,
	.shadow_reg_value_7  = 0x0003201C,
	.shadow_reg_value_8  = 0x00032020,
	.shadow_reg_value_9  = 0x00032024,
	.shadow_reg_value_10 = 0x00032028,
	.shadow_reg_value_11 = 0x0003202C,
	.shadow_reg_value_12 = 0x00032030,
	.shadow_reg_value_13 = 0x00032034,
	.shadow_reg_value_14 = 0x00032038,
	.shadow_reg_value_15 = 0x0003203C,
	.shadow_reg_value_16 = 0x00032040,
	.shadow_reg_value_17 = 0x00032044,
	.shadow_reg_value_18 = 0x00032048,
	.shadow_reg_value_19 = 0x0003204C,
	.shadow_reg_value_20 = 0x00032050,
	.shadow_reg_value_21 = 0x00032054,
	.shadow_reg_value_22 = 0x00032058,
	.shadow_reg_value_23 = 0x0003205C
};

struct ath10k_shadow_reg_address wcn3990_shadow_reg_address = {
	.shadow_reg_address_0  = 0x00030020,
	.shadow_reg_address_1  = 0x00030024,
	.shadow_reg_address_2  = 0x00030028,
	.shadow_reg_address_3  = 0x0003002C,
	.shadow_reg_address_4  = 0x00030030,
	.shadow_reg_address_5  = 0x00030034,
	.shadow_reg_address_6  = 0x00030038,
	.shadow_reg_address_7  = 0x0003003C,
	.shadow_reg_address_8  = 0x00030040,
	.shadow_reg_address_9  = 0x00030044,
	.shadow_reg_address_10 = 0x00030048,
	.shadow_reg_address_11 = 0x0003004C,
	.shadow_reg_address_12 = 0x00030050,
	.shadow_reg_address_13 = 0x00030054,
	.shadow_reg_address_14 = 0x00030058,
	.shadow_reg_address_15 = 0x0003005C,
	.shadow_reg_address_16 = 0x00030060,
	.shadow_reg_address_17 = 0x00030064,
	.shadow_reg_address_18 = 0x00030068,
	.shadow_reg_address_19 = 0x0003006C,
	.shadow_reg_address_20 = 0x00030070,
	.shadow_reg_address_21 = 0x00030074,
	.shadow_reg_address_22 = 0x00030078,
	.shadow_reg_address_23 = 0x0003007C
};

void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
				u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
{
Loading