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

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

ARCv2: mm: Merge 2 updates to DC_CTRL for region flush



Region Flush has a weird programming model.

 1. Flush or Invalidate is selected by DC_CTRL.RGN_OP
 2 Flush-n-Invalidate is done by DC_CTRL.IM

Given the code structuring before, case #2 above was generating two
seperate updates to DC_CTRL which was pointless.

| 80a342b0 <__dma_cache_wback_inv_l1>:
| 80a342b0:	clri	r4
| 80a342b4:	lr	r2,[dc_ctrl]
| 80a342b8:	bset_s	r2,r2,0x6
| 80a342ba:	sr	r2,[dc_ctrl]	<-- FIRST
|
| 80a342be:	bmskn	r3,r0,0x5
|
| 80a342c2:	lr	r2,[dc_ctrl]
| 80a342c6:	and	r2,r2,0xfffff1ff
| 80a342ce:	bset_s	r2,r2,0x9
| 80a342d0:	sr	r2,[dc_ctrl]	<-- SECOND
|
| 80a342d4:	add_s	r1,r1,0x3f
| 80a342d6:	bmsk_s	r0,r0,0x5
| 80a342d8:	add_s	r0,r0,r1
| 80a342da:	add_s	r0,r0,r3
| 80a342dc:	sr	r0,[78]
| 80a342e0:	sr	r3,[77]
|...
|...

So move setting of DC_CTRL.RGN_OP into __before_dc_op() and combine with
any other update.

| 80b63324 <__dma_cache_wback_inv_l1>:
| 80b63324:	clri	r3
| 80b63328:	lr	r2,[dc_ctrl]
| 80b6332c:	and	r2,r2,0xfffff1ff
| 80b63334:	or	r2,r2,576
| 80b63338:	sr	r2,[dc_ctrl]
|
| 80b6333c:	add_s	r1,r1,0x3f
| 80b6333e:	bmskn	r2,r0,0x5
| 80b63342:	add_s	r0,r0,r1
| 80b63344:	sr	r0,[78]
| 80b63348:	sr	r2,[77]

Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent 0d77117f
Loading
Loading
Loading
Loading
+32 −14
Original line number Diff line number Diff line
@@ -409,8 +409,7 @@ static inline
void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
			  unsigned long sz, const int op, const int full_page)
{
	const unsigned int ctl = ARC_REG_DC_CTRL;
	unsigned int s, e, val;
	unsigned int s, e;

	/* Only for Non aliasing I-cache in HS38 */
	if (op == OP_INV_IC) {
@@ -441,18 +440,6 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
			write_aux_reg(ARC_REG_DC_PTAG_HI, (u64)paddr >> 32);
	}

	/*
	 * Flush / Invalidate is provided by DC_CTRL.RNG_OP 0 or 1
	 * Flush-n-invalidate additionally uses setting DC_CTRL.IM = 1
	 * just as for line ops which is handled in __before_dc_op()
	 */
	val = read_aux_reg(ctl) & ~DC_CTRL_RGN_OP_MSK;

	if (op & OP_INV)
		val |= DC_CTRL_RGN_OP_INV;

	write_aux_reg(ctl, val);

	/* ENDR needs to be set ahead of START */
	write_aux_reg(e, paddr + sz);	/* ENDR is exclusive */
	write_aux_reg(s, paddr);
@@ -476,6 +463,11 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
 * Machine specific helpers for Entire D-Cache or Per Line ops
 */

#ifndef USE_RGN_FLSH
/*
 * this version avoids extra read/write of DC_CTRL for flush or invalid ops
 * in the non region flush regime (such as for ARCompact)
 */
static inline void __before_dc_op(const int op)
{
	if (op == OP_FLUSH_N_INV) {
@@ -489,6 +481,32 @@ static inline void __before_dc_op(const int op)
	}
}

#else

static inline void __before_dc_op(const int op)
{
	const unsigned int ctl = ARC_REG_DC_CTRL;
	unsigned int val = read_aux_reg(ctl);

	if (op == OP_FLUSH_N_INV) {
		val |= DC_CTRL_INV_MODE_FLUSH;
	}

	if (op != OP_INV_IC) {
		/*
		 * Flush / Invalidate is provided by DC_CTRL.RNG_OP 0 or 1
		 * combined Flush-n-invalidate uses DC_CTRL.IM = 1 set above
		 */
		val &= ~DC_CTRL_RGN_OP_MSK;
		if (op & OP_INV)
			val |= DC_CTRL_RGN_OP_INV;
	}
	write_aux_reg(ctl, val);
}

#endif


static inline void __after_dc_op(const int op)
{
	if (op & OP_FLUSH) {