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

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

Merge "coresight: byte-cntr: Add scatter-gather support for byte-counter" into msm-4.14

parents 52f6e1ff cff30612
Loading
Loading
Loading
Loading
+111 −13
Original line number Diff line number Diff line
@@ -24,17 +24,94 @@
static struct tmc_drvdata *tmcdrvdata;

static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos,
			       size_t bytes, size_t *len)
			       size_t bytes, size_t *len, char **bufp)
{
	if (*len >= bytes) {

	if (*bufp >= (char *)(tmcdrvdata->vaddr + tmcdrvdata->size))
		*bufp = tmcdrvdata->vaddr;

	if (*len >= bytes)
		*len = bytes;
	else if (((uint32_t)*ppos % bytes) + *len > bytes)
		*len = bytes - ((uint32_t)*ppos % bytes);

	if ((*bufp + *len) > (char *)(tmcdrvdata->vaddr +
		tmcdrvdata->size))
		*len = (char *)(tmcdrvdata->vaddr + tmcdrvdata->size) -
			*bufp;
	if (*len == bytes || (*len + (uint32_t)*ppos) % bytes == 0)
		atomic_dec(&byte_cntr_data->irq_cnt);
}

static void tmc_etr_sg_read_pos(loff_t *ppos,
				size_t bytes, bool noirq, size_t *len,
				char **bufpp)
{
	uint32_t rwp, i = 0;
	uint32_t blk_num, sg_tbl_num, blk_num_loc, read_off;
	uint32_t *virt_pte, *virt_st_tbl;
	void *virt_blk;
	phys_addr_t phys_pte;
	int total_ents = DIV_ROUND_UP(tmcdrvdata->size, PAGE_SIZE);
	int ents_per_pg = PAGE_SIZE/sizeof(uint32_t);

	if (*len == 0)
		return;

	blk_num = *ppos / PAGE_SIZE;
	read_off = *ppos % PAGE_SIZE;

	virt_st_tbl = (uint32_t *)tmcdrvdata->vaddr;

	/* Compute table index and block entry index within that table */
	if (blk_num && (blk_num == (total_ents - 1)) &&
	    !(blk_num % (ents_per_pg - 1))) {
		sg_tbl_num = blk_num / ents_per_pg;
		blk_num_loc = ents_per_pg - 1;
	} else {
		sg_tbl_num = blk_num / (ents_per_pg - 1);
		blk_num_loc = blk_num % (ents_per_pg - 1);
	}

	for (i = 0; i < sg_tbl_num; i++) {
		virt_pte = virt_st_tbl + (ents_per_pg - 1);
		phys_pte = TMC_ETR_SG_ENT_TO_BLK(*virt_pte);
		virt_st_tbl = (uint32_t *)phys_to_virt(phys_pte);
	}

	virt_pte = virt_st_tbl + blk_num_loc;
	phys_pte = TMC_ETR_SG_ENT_TO_BLK(*virt_pte);
	virt_blk = phys_to_virt(phys_pte);

	*bufpp = (char *)(virt_blk + read_off);

	if (noirq) {
		rwp = readl_relaxed(tmcdrvdata->base + TMC_RWP);
		tmc_etr_sg_rwp_pos(tmcdrvdata, rwp);
		if (tmcdrvdata->sg_blk_num == blk_num &&
		    rwp >= (phys_pte + read_off))
			*len = rwp - phys_pte - read_off;
		else if (tmcdrvdata->sg_blk_num > blk_num)
			*len = PAGE_SIZE - read_off;
		else
			*len = bytes;
	} else {
		if (((uint32_t)*ppos % bytes) + *len > bytes)

		if (*len > (PAGE_SIZE - read_off))
			*len = PAGE_SIZE - read_off;

		if (*len >= (bytes - ((uint32_t)*ppos % bytes)))
			*len = bytes - ((uint32_t)*ppos % bytes);
		if ((*len + (uint32_t)*ppos) % bytes == 0)
			atomic_dec(&byte_cntr_data->irq_cnt);

		if (*len == bytes || (*len + (uint32_t)*ppos) % bytes == 0)
			atomic_dec(&tmcdrvdata->byte_cntr->irq_cnt);
	}

	/*
	 * Invalidate cache range before reading. This will make sure that CPU
	 * reads latest contents from DDR
	 */
	dmac_inv_range((void *)(*bufpp), (void *)(*bufpp) + *len);
}

static irqreturn_t etr_handler(int irq, void *data)
@@ -73,6 +150,8 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
	if (!byte_cntr_data->read_active)
		goto err0;

	bufp = (char *)(tmcdrvdata->buf + *ppos);

	if (byte_cntr_data->enable) {
		if (!atomic_read(&byte_cntr_data->irq_cnt)) {
			mutex_unlock(&byte_cntr_data->byte_cntr_lock);
@@ -83,19 +162,38 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
			if (!byte_cntr_data->read_active)
				goto err0;
		}
		bufp = (char *)(tmcdrvdata->vaddr + *ppos);

		if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
			tmc_etr_read_bytes(byte_cntr_data, ppos,
					byte_cntr_data->block_size, &len);
					   byte_cntr_data->block_size, &len,
					   &bufp);
		else
			tmc_etr_sg_read_pos(ppos, byte_cntr_data->block_size, 0,
					    &len, &bufp);

	} else {
		if (!atomic_read(&byte_cntr_data->irq_cnt)) {
			tmc_etr_flush_bytes(ppos, byte_cntr_data->block_size,
			if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
				tmc_etr_flush_bytes(ppos,
						    byte_cntr_data->block_size,
						    &len);
			else
				tmc_etr_sg_read_pos(ppos,
						    byte_cntr_data->block_size,
						    1,
						    &len, &bufp);
			if (!len)
				goto err0;
		} else {
			if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
				tmc_etr_read_bytes(byte_cntr_data, ppos,
					byte_cntr_data->block_size, &len);
						   byte_cntr_data->block_size,
						   &len, &bufp);
			else
				tmc_etr_sg_read_pos(ppos,
						    byte_cntr_data->block_size,
						    1,
						    &len, &bufp);
		}
	}

+1 −2
Original line number Diff line number Diff line
@@ -433,12 +433,11 @@ void tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
	writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE);

	axictl = readl_relaxed(drvdata->base + TMC_AXICTL);
	axictl &= ~TMC_AXICTL_CLEAR_MASK;
	if (drvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG)
		axictl &= ~TMC_AXICTL_SCT_GAT_MODE;
	else
		axictl |= TMC_AXICTL_SCT_GAT_MODE;
	writel_relaxed(axictl, drvdata->base + TMC_AXICTL);
	axictl &= ~TMC_AXICTL_CLEAR_MASK;
	axictl |= (TMC_AXICTL_PROT_CTL_B1 | TMC_AXICTL_WR_BURST_16);
	axictl |= TMC_AXICTL_AXCACHE_OS;

+1 −0
Original line number Diff line number Diff line
@@ -272,6 +272,7 @@ extern struct byte_cntr *byte_cntr_init(struct amba_device *adev,
extern const struct coresight_ops tmc_etr_cs_ops;
extern void tmc_etr_sg_rwp_pos(struct tmc_drvdata *drvdata, uint32_t rwp);

extern const struct coresight_ops tmc_etr_cs_ops;

#define TMC_REG_PAIR(name, lo_off, hi_off)				\
static inline u64							\