180 lines
		
	
	
	
		
			3.9 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			180 lines
		
	
	
	
		
			3.9 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#ifndef __ASMARM_CTI_H
							 | 
						||
| 
								 | 
							
								#define __ASMARM_CTI_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include	<asm/io.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* The registers' definition is from section 3.2 of
							 | 
						||
| 
								 | 
							
								 * Embedded Cross Trigger Revision: r0p0
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#define		CTICONTROL		0x000
							 | 
						||
| 
								 | 
							
								#define		CTISTATUS		0x004
							 | 
						||
| 
								 | 
							
								#define		CTILOCK			0x008
							 | 
						||
| 
								 | 
							
								#define		CTIPROTECTION		0x00C
							 | 
						||
| 
								 | 
							
								#define		CTIINTACK		0x010
							 | 
						||
| 
								 | 
							
								#define		CTIAPPSET		0x014
							 | 
						||
| 
								 | 
							
								#define		CTIAPPCLEAR		0x018
							 | 
						||
| 
								 | 
							
								#define		CTIAPPPULSE		0x01c
							 | 
						||
| 
								 | 
							
								#define		CTIINEN			0x020
							 | 
						||
| 
								 | 
							
								#define		CTIOUTEN		0x0A0
							 | 
						||
| 
								 | 
							
								#define		CTITRIGINSTATUS		0x130
							 | 
						||
| 
								 | 
							
								#define		CTITRIGOUTSTATUS	0x134
							 | 
						||
| 
								 | 
							
								#define		CTICHINSTATUS		0x138
							 | 
						||
| 
								 | 
							
								#define		CTICHOUTSTATUS		0x13c
							 | 
						||
| 
								 | 
							
								#define		CTIPERIPHID0		0xFE0
							 | 
						||
| 
								 | 
							
								#define		CTIPERIPHID1		0xFE4
							 | 
						||
| 
								 | 
							
								#define		CTIPERIPHID2		0xFE8
							 | 
						||
| 
								 | 
							
								#define		CTIPERIPHID3		0xFEC
							 | 
						||
| 
								 | 
							
								#define		CTIPCELLID0		0xFF0
							 | 
						||
| 
								 | 
							
								#define		CTIPCELLID1		0xFF4
							 | 
						||
| 
								 | 
							
								#define		CTIPCELLID2		0xFF8
							 | 
						||
| 
								 | 
							
								#define		CTIPCELLID3		0xFFC
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* The below are from section 3.6.4 of
							 | 
						||
| 
								 | 
							
								 * CoreSight v1.0 Architecture Specification
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#define		LOCKACCESS		0xFB0
							 | 
						||
| 
								 | 
							
								#define		LOCKSTATUS		0xFB4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* write this value to LOCKACCESS will unlock the module, and
							 | 
						||
| 
								 | 
							
								 * other value will lock the module
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#define		LOCKCODE		0xC5ACCE55
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * struct cti - cross trigger interface struct
							 | 
						||
| 
								 | 
							
								 * @base: mapped virtual address for the cti base
							 | 
						||
| 
								 | 
							
								 * @irq: irq number for the cti
							 | 
						||
| 
								 | 
							
								 * @trig_out_for_irq: triger out number which will cause
							 | 
						||
| 
								 | 
							
								 *	the @irq happen
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * cti struct used to operate cti registers.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								struct cti {
							 | 
						||
| 
								 | 
							
									void __iomem *base;
							 | 
						||
| 
								 | 
							
									int irq;
							 | 
						||
| 
								 | 
							
									int trig_out_for_irq;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * cti_init - initialize the cti instance
							 | 
						||
| 
								 | 
							
								 * @cti: cti instance
							 | 
						||
| 
								 | 
							
								 * @base: mapped virtual address for the cti base
							 | 
						||
| 
								 | 
							
								 * @irq: irq number for the cti
							 | 
						||
| 
								 | 
							
								 * @trig_out: triger out number which will cause
							 | 
						||
| 
								 | 
							
								 *	the @irq happen
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * called by machine code to pass the board dependent
							 | 
						||
| 
								 | 
							
								 * @base, @irq and @trig_out to cti.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static inline void cti_init(struct cti *cti,
							 | 
						||
| 
								 | 
							
									void __iomem *base, int irq, int trig_out)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									cti->base = base;
							 | 
						||
| 
								 | 
							
									cti->irq  = irq;
							 | 
						||
| 
								 | 
							
									cti->trig_out_for_irq = trig_out;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * cti_map_trigger - use the @chan to map @trig_in to @trig_out
							 | 
						||
| 
								 | 
							
								 * @cti: cti instance
							 | 
						||
| 
								 | 
							
								 * @trig_in: trigger in number
							 | 
						||
| 
								 | 
							
								 * @trig_out: trigger out number
							 | 
						||
| 
								 | 
							
								 * @channel: channel number
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This function maps one trigger in of @trig_in to one trigger
							 | 
						||
| 
								 | 
							
								 * out of @trig_out using the channel @chan.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static inline void cti_map_trigger(struct cti *cti,
							 | 
						||
| 
								 | 
							
									int trig_in, int trig_out, int chan)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									void __iomem *base = cti->base;
							 | 
						||
| 
								 | 
							
									unsigned long val;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									val = __raw_readl(base + CTIINEN + trig_in * 4);
							 | 
						||
| 
								 | 
							
									val |= BIT(chan);
							 | 
						||
| 
								 | 
							
									__raw_writel(val, base + CTIINEN + trig_in * 4);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									val = __raw_readl(base + CTIOUTEN + trig_out * 4);
							 | 
						||
| 
								 | 
							
									val |= BIT(chan);
							 | 
						||
| 
								 | 
							
									__raw_writel(val, base + CTIOUTEN + trig_out * 4);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * cti_enable - enable the cti module
							 | 
						||
| 
								 | 
							
								 * @cti: cti instance
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * enable the cti module
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static inline void cti_enable(struct cti *cti)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									__raw_writel(0x1, cti->base + CTICONTROL);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * cti_disable - disable the cti module
							 | 
						||
| 
								 | 
							
								 * @cti: cti instance
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * enable the cti module
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static inline void cti_disable(struct cti *cti)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									__raw_writel(0, cti->base + CTICONTROL);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * cti_irq_ack - clear the cti irq
							 | 
						||
| 
								 | 
							
								 * @cti: cti instance
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * clear the cti irq
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static inline void cti_irq_ack(struct cti *cti)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									void __iomem *base = cti->base;
							 | 
						||
| 
								 | 
							
									unsigned long val;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									val = __raw_readl(base + CTIINTACK);
							 | 
						||
| 
								 | 
							
									val |= BIT(cti->trig_out_for_irq);
							 | 
						||
| 
								 | 
							
									__raw_writel(val, base + CTIINTACK);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * cti_unlock - unlock cti module
							 | 
						||
| 
								 | 
							
								 * @cti: cti instance
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * unlock the cti module, or else any writes to the cti
							 | 
						||
| 
								 | 
							
								 * module is not allowed.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static inline void cti_unlock(struct cti *cti)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									void __iomem *base = cti->base;
							 | 
						||
| 
								 | 
							
									unsigned long val;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									val = __raw_readl(base + LOCKSTATUS);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (val & 1) {
							 | 
						||
| 
								 | 
							
										val = LOCKCODE;
							 | 
						||
| 
								 | 
							
										__raw_writel(val, base + LOCKACCESS);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * cti_lock - lock cti module
							 | 
						||
| 
								 | 
							
								 * @cti: cti instance
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * lock the cti module, so any writes to the cti
							 | 
						||
| 
								 | 
							
								 * module will be not allowed.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static inline void cti_lock(struct cti *cti)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									void __iomem *base = cti->base;
							 | 
						||
| 
								 | 
							
									unsigned long val;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									val = __raw_readl(base + LOCKSTATUS);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (!(val & 1)) {
							 | 
						||
| 
								 | 
							
										val = ~LOCKCODE;
							 | 
						||
| 
								 | 
							
										__raw_writel(val, base + LOCKACCESS);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 |