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

Commit ae0b63d9 authored by Vineet Gupta's avatar Vineet Gupta
Browse files

ARCv2: SLC: provide a line based flush routine for debugging

parent 9f82e90a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -96,6 +96,8 @@ extern unsigned long perip_base, perip_end;
#define ARC_REG_SLC_CTRL	0x903
#define ARC_REG_SLC_FLUSH	0x904
#define ARC_REG_SLC_INVALIDATE	0x905
#define ARC_AUX_SLC_IVDL	0x910
#define ARC_AUX_SLC_FLDL	0x912
#define ARC_REG_SLC_RGN_START	0x914
#define ARC_REG_SLC_RGN_START1	0x915
#define ARC_REG_SLC_RGN_END	0x916
+53 −1
Original line number Diff line number Diff line
@@ -652,7 +652,7 @@ static void __ic_line_inv_vaddr(phys_addr_t paddr, unsigned long vaddr,

#endif /* CONFIG_ARC_HAS_ICACHE */

noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
noinline void slc_op_rgn(phys_addr_t paddr, unsigned long sz, const int op)
{
#ifdef CONFIG_ISA_ARCV2
	/*
@@ -715,6 +715,58 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
#endif
}

noinline void slc_op_line(phys_addr_t paddr, unsigned long sz, const int op)
{
#ifdef CONFIG_ISA_ARCV2
	/*
	 * SLC is shared between all cores and concurrent aux operations from
	 * multiple cores need to be serialized using a spinlock
	 * A concurrent operation can be silently ignored and/or the old/new
	 * operation can remain incomplete forever (lockup in SLC_CTRL_BUSY loop
	 * below)
	 */
	static DEFINE_SPINLOCK(lock);

	const unsigned long SLC_LINE_MASK = ~(l2_line_sz - 1);
	unsigned int ctrl, cmd;
	unsigned long flags;
	int num_lines;

	spin_lock_irqsave(&lock, flags);

	ctrl = read_aux_reg(ARC_REG_SLC_CTRL);

	/* Don't rely on default value of IM bit */
	if (!(op & OP_FLUSH))		/* i.e. OP_INV */
		ctrl &= ~SLC_CTRL_IM;	/* clear IM: Disable flush before Inv */
	else
		ctrl |= SLC_CTRL_IM;

	write_aux_reg(ARC_REG_SLC_CTRL, ctrl);

	cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL;

	sz += paddr & ~SLC_LINE_MASK;
	paddr &= SLC_LINE_MASK;

	num_lines = DIV_ROUND_UP(sz, l2_line_sz);

	while (num_lines-- > 0) {
		write_aux_reg(cmd, paddr);
		paddr += l2_line_sz;
	}

	/* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
	read_aux_reg(ARC_REG_SLC_CTRL);

	while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY);

	spin_unlock_irqrestore(&lock, flags);
#endif
}

#define slc_op(paddr, sz, op)	slc_op_rgn(paddr, sz, op)

noinline static void slc_entire_op(const int op)
{
	unsigned int ctrl, r = ARC_REG_SLC_CTRL;