forked from Mirrors/opensbi
		
	lib: utils/timer: Allow ACLINT MTIMER driver to setup quirks
The quirks checking will cause ACLINT step into a CLINT code path, this is not expected when ACLINT needs custom quirks. Add a new quirk to identify custom ACLINT, and apply the general quirks after applying CLINT specific quirks. Signed-off-by: Inochi Amaoto <inochiama@outlook.com> Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
		
				
					committed by
					
						
						Anup Patel
					
				
			
			
				
	
			
			
			
						parent
						
							d1e0f7f25b
						
					
				
				
					commit
					896d2c99e2
				
			@@ -16,9 +16,10 @@
 | 
			
		||||
#include <sbi_utils/timer/aclint_mtimer.h>
 | 
			
		||||
 | 
			
		||||
struct timer_mtimer_quirks {
 | 
			
		||||
	unsigned int	mtime_offset;
 | 
			
		||||
	bool		is_clint;
 | 
			
		||||
	unsigned int	clint_mtime_offset;
 | 
			
		||||
	bool		clint_without_mtime;
 | 
			
		||||
	bool		has_64bit_mmio;
 | 
			
		||||
	bool		without_mtime;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct timer_mtimer_node {
 | 
			
		||||
@@ -36,6 +37,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 | 
			
		||||
	unsigned long addr[2], size[2];
 | 
			
		||||
	struct timer_mtimer_node *mtn, *n;
 | 
			
		||||
	struct aclint_mtimer_data *mt;
 | 
			
		||||
	const struct timer_mtimer_quirks *quirks = match->data;
 | 
			
		||||
 | 
			
		||||
	mtn = sbi_zalloc(sizeof(*mtn));
 | 
			
		||||
	if (!mtn)
 | 
			
		||||
@@ -58,24 +60,20 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 | 
			
		||||
		return rc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (match->data) { /* SiFive CLINT */
 | 
			
		||||
		const struct timer_mtimer_quirks *quirks = match->data;
 | 
			
		||||
 | 
			
		||||
	if (quirks && quirks->is_clint) { /* SiFive CLINT */
 | 
			
		||||
		/* Set CLINT addresses */
 | 
			
		||||
		mt->mtimecmp_addr = addr[0] + ACLINT_DEFAULT_MTIMECMP_OFFSET;
 | 
			
		||||
		mt->mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE;
 | 
			
		||||
		if (!quirks->without_mtime) {
 | 
			
		||||
		if (!quirks->clint_without_mtime) {
 | 
			
		||||
			mt->mtime_addr = addr[0] + ACLINT_DEFAULT_MTIME_OFFSET;
 | 
			
		||||
			mt->mtime_size = size[0] - mt->mtimecmp_size;
 | 
			
		||||
			/* Adjust MTIMER address and size for CLINT device */
 | 
			
		||||
			mt->mtime_addr += quirks->mtime_offset;
 | 
			
		||||
			mt->mtime_size -= quirks->mtime_offset;
 | 
			
		||||
			mt->mtime_addr += quirks->clint_mtime_offset;
 | 
			
		||||
			mt->mtime_size -= quirks->clint_mtime_offset;
 | 
			
		||||
		} else {
 | 
			
		||||
			mt->mtime_addr = mt->mtime_size = 0;
 | 
			
		||||
		}
 | 
			
		||||
		mt->mtimecmp_addr += quirks->mtime_offset;
 | 
			
		||||
		/* Apply additional CLINT quirks */
 | 
			
		||||
		mt->has_64bit_mmio = quirks->has_64bit_mmio;
 | 
			
		||||
		mt->mtimecmp_addr += quirks->clint_mtime_offset;
 | 
			
		||||
	} else { /* RISC-V ACLINT MTIMER */
 | 
			
		||||
		/* Set ACLINT MTIMER addresses */
 | 
			
		||||
		mt->mtime_addr = addr[0];
 | 
			
		||||
@@ -84,6 +82,11 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 | 
			
		||||
		mt->mtimecmp_size = size[1];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Apply additional quirks */
 | 
			
		||||
	if (quirks) {
 | 
			
		||||
		mt->has_64bit_mmio = quirks->has_64bit_mmio;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check if MTIMER device has shared MTIME address */
 | 
			
		||||
	if (mt->mtime_size) {
 | 
			
		||||
		mt->has_shared_mtime = false;
 | 
			
		||||
@@ -133,13 +136,15 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct timer_mtimer_quirks sifive_clint_quirks = {
 | 
			
		||||
	.mtime_offset	= CLINT_MTIMER_OFFSET,
 | 
			
		||||
	.has_64bit_mmio	= true,
 | 
			
		||||
	.is_clint		= true,
 | 
			
		||||
	.clint_mtime_offset	= CLINT_MTIMER_OFFSET,
 | 
			
		||||
	.has_64bit_mmio		= true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct timer_mtimer_quirks thead_clint_quirks = {
 | 
			
		||||
	.mtime_offset	= CLINT_MTIMER_OFFSET,
 | 
			
		||||
	.without_mtime  = true,
 | 
			
		||||
	.is_clint		= true,
 | 
			
		||||
	.clint_mtime_offset	= CLINT_MTIMER_OFFSET,
 | 
			
		||||
	.clint_without_mtime	= true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct fdt_match timer_mtimer_match[] = {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user