Skip to content

Commit

Permalink
drivers: irqsteer: adjust CHn_MASK index computation
Browse files Browse the repository at this point in the history
For IRQ_STEER, lower CHn_MASK register indexes are used
to mask higher interrupt IDs. For instance, in the case
of i.MX8MP, the mapping is as follows:

	CHn_MASK4 => masks interrupts [31:0]
	CHn_MASK3 => masks interrupts [63:32]
	CHn_MASK2 => masks interrupts [95:64]
	CHn_MASK1 => masks interrupts [127:96]
	CHn_MASK0 => masks interrupts [159:128]

The `IRQSTEER_GetRegIndex()` function is used to fetch
the CHn_MASK register index based on a given slice. The term
"slice" is used to refer to an index of a CHn_MASK register in
the set of CHn_MASK registers assigned to a certain master. Assuming
the following partition scheme (i.MX8MP):

	{ CHn_MASK4 } is assigned to MASTER0
	{ CHn_MASK3, CHn_MASK2 } is assigned to MASTER1
	{ CHn_MASK1, CHn_MASK0 } is assiged to MASTER2

CHn_MASK3 would be at slice (index) 0, CHn_MASK2 would be at
slice 1, CHn_MASK1 would be at slice 0 and so on.

To compute the CHn_MASK register index found at a given slice,
`IRQSTEER_GetRegIndex()` uses a base index, which is either
the lowest or the highest CHn_MASK register index in a master's
partition (for instance, for MASTER1 the higher would be 3 and
the lowest would be 2).

For IRQ_STEER instances with an uneven number of CHn_MASK registers
the base is the lowest index, while in the case of instances with
an even number of CHn_MASK registers it's exactly the opposite. This
is an issue because the software using this function might expect
the base to either be the lowest or the highest index ALL THE TIME
(since this affects the order in which the CHn_MASK register indexes
are returned).

As such, fix this problem by making the base the highest CHn_MASK
register index.

Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
  • Loading branch information
LaurentiuM1234 committed May 22, 2024
1 parent 644e6de commit 3104119
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions mcux/mcux-sdk/drivers/irqsteer/fsl_irqsteer.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,16 @@ uint32_t IRQSTEER_GetMasterIrqCount(IRQSTEER_Type *base, irqsteer_int_master_t i
return count;
}

static uint32_t IRQSTEER_GetRegIndex(irqsteer_int_master_t intMasterIndex, uint32_t slice)
static uint32_t IRQSTEER_GetRegIndex(irqsteer_int_master_t intMasterIndex,
uint32_t slice, uint32_t sliceNum)
{
uint32_t base = FSL_FEATURE_IRQSTEER_CHn_MASK_COUNT - 1 - intMasterIndex * 2;

if (FSL_FEATURE_IRQSTEER_CHn_MASK_COUNT % 2) {
return base + slice;
} else {
return base - slice;
base += sliceNum - 1;
}

return base - slice;
}

/*!
Expand Down Expand Up @@ -225,7 +226,7 @@ IRQn_Type IRQSTEER_GetMasterNextInterrupt(IRQSTEER_Type *base, irqsteer_int_mast
bitOffset = 0;

/* compute the index of the register to be queried */
regIndex = IRQSTEER_GetRegIndex(intMasterIndex, i);
regIndex = IRQSTEER_GetRegIndex(intMasterIndex, i, sliceNum + 1);

/* get register's value */
chanStatus = base->CHn_STATUS[regIndex];
Expand Down Expand Up @@ -255,7 +256,7 @@ uint64_t IRQSTEER_GetMasterInterruptsStatus(IRQSTEER_Type *base, irqsteer_int_ma
sliceNum = IRQSTEER_GetMasterIrqCount(base, intMasterIndex) / 32 - 1;

for (i = 0; i <= sliceNum; i++) {
regIndex = IRQSTEER_GetRegIndex(intMasterIndex, i);
regIndex = IRQSTEER_GetRegIndex(intMasterIndex, i, sliceNum + 1);

chanStatus = base->CHn_STATUS[regIndex];

Expand Down

0 comments on commit 3104119

Please sign in to comment.