162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASMARM_CTI_H
362306a36Sopenharmony_ci#define __ASMARM_CTI_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include	<asm/io.h>
662306a36Sopenharmony_ci#include	<asm/hardware/coresight.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/* The registers' definition is from section 3.2 of
962306a36Sopenharmony_ci * Embedded Cross Trigger Revision: r0p0
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci#define		CTICONTROL		0x000
1262306a36Sopenharmony_ci#define		CTISTATUS		0x004
1362306a36Sopenharmony_ci#define		CTILOCK			0x008
1462306a36Sopenharmony_ci#define		CTIPROTECTION		0x00C
1562306a36Sopenharmony_ci#define		CTIINTACK		0x010
1662306a36Sopenharmony_ci#define		CTIAPPSET		0x014
1762306a36Sopenharmony_ci#define		CTIAPPCLEAR		0x018
1862306a36Sopenharmony_ci#define		CTIAPPPULSE		0x01c
1962306a36Sopenharmony_ci#define		CTIINEN			0x020
2062306a36Sopenharmony_ci#define		CTIOUTEN		0x0A0
2162306a36Sopenharmony_ci#define		CTITRIGINSTATUS		0x130
2262306a36Sopenharmony_ci#define		CTITRIGOUTSTATUS	0x134
2362306a36Sopenharmony_ci#define		CTICHINSTATUS		0x138
2462306a36Sopenharmony_ci#define		CTICHOUTSTATUS		0x13c
2562306a36Sopenharmony_ci#define		CTIPERIPHID0		0xFE0
2662306a36Sopenharmony_ci#define		CTIPERIPHID1		0xFE4
2762306a36Sopenharmony_ci#define		CTIPERIPHID2		0xFE8
2862306a36Sopenharmony_ci#define		CTIPERIPHID3		0xFEC
2962306a36Sopenharmony_ci#define		CTIPCELLID0		0xFF0
3062306a36Sopenharmony_ci#define		CTIPCELLID1		0xFF4
3162306a36Sopenharmony_ci#define		CTIPCELLID2		0xFF8
3262306a36Sopenharmony_ci#define		CTIPCELLID3		0xFFC
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/* The below are from section 3.6.4 of
3562306a36Sopenharmony_ci * CoreSight v1.0 Architecture Specification
3662306a36Sopenharmony_ci */
3762306a36Sopenharmony_ci#define		LOCKACCESS		0xFB0
3862306a36Sopenharmony_ci#define		LOCKSTATUS		0xFB4
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/**
4162306a36Sopenharmony_ci * struct cti - cross trigger interface struct
4262306a36Sopenharmony_ci * @base: mapped virtual address for the cti base
4362306a36Sopenharmony_ci * @irq: irq number for the cti
4462306a36Sopenharmony_ci * @trig_out_for_irq: triger out number which will cause
4562306a36Sopenharmony_ci *	the @irq happen
4662306a36Sopenharmony_ci *
4762306a36Sopenharmony_ci * cti struct used to operate cti registers.
4862306a36Sopenharmony_ci */
4962306a36Sopenharmony_cistruct cti {
5062306a36Sopenharmony_ci	void __iomem *base;
5162306a36Sopenharmony_ci	int irq;
5262306a36Sopenharmony_ci	int trig_out_for_irq;
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/**
5662306a36Sopenharmony_ci * cti_init - initialize the cti instance
5762306a36Sopenharmony_ci * @cti: cti instance
5862306a36Sopenharmony_ci * @base: mapped virtual address for the cti base
5962306a36Sopenharmony_ci * @irq: irq number for the cti
6062306a36Sopenharmony_ci * @trig_out: triger out number which will cause
6162306a36Sopenharmony_ci *	the @irq happen
6262306a36Sopenharmony_ci *
6362306a36Sopenharmony_ci * called by machine code to pass the board dependent
6462306a36Sopenharmony_ci * @base, @irq and @trig_out to cti.
6562306a36Sopenharmony_ci */
6662306a36Sopenharmony_cistatic inline void cti_init(struct cti *cti,
6762306a36Sopenharmony_ci	void __iomem *base, int irq, int trig_out)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	cti->base = base;
7062306a36Sopenharmony_ci	cti->irq  = irq;
7162306a36Sopenharmony_ci	cti->trig_out_for_irq = trig_out;
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci/**
7562306a36Sopenharmony_ci * cti_map_trigger - use the @chan to map @trig_in to @trig_out
7662306a36Sopenharmony_ci * @cti: cti instance
7762306a36Sopenharmony_ci * @trig_in: trigger in number
7862306a36Sopenharmony_ci * @trig_out: trigger out number
7962306a36Sopenharmony_ci * @channel: channel number
8062306a36Sopenharmony_ci *
8162306a36Sopenharmony_ci * This function maps one trigger in of @trig_in to one trigger
8262306a36Sopenharmony_ci * out of @trig_out using the channel @chan.
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_cistatic inline void cti_map_trigger(struct cti *cti,
8562306a36Sopenharmony_ci	int trig_in, int trig_out, int chan)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	void __iomem *base = cti->base;
8862306a36Sopenharmony_ci	unsigned long val;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	val = __raw_readl(base + CTIINEN + trig_in * 4);
9162306a36Sopenharmony_ci	val |= BIT(chan);
9262306a36Sopenharmony_ci	__raw_writel(val, base + CTIINEN + trig_in * 4);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	val = __raw_readl(base + CTIOUTEN + trig_out * 4);
9562306a36Sopenharmony_ci	val |= BIT(chan);
9662306a36Sopenharmony_ci	__raw_writel(val, base + CTIOUTEN + trig_out * 4);
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci/**
10062306a36Sopenharmony_ci * cti_enable - enable the cti module
10162306a36Sopenharmony_ci * @cti: cti instance
10262306a36Sopenharmony_ci *
10362306a36Sopenharmony_ci * enable the cti module
10462306a36Sopenharmony_ci */
10562306a36Sopenharmony_cistatic inline void cti_enable(struct cti *cti)
10662306a36Sopenharmony_ci{
10762306a36Sopenharmony_ci	__raw_writel(0x1, cti->base + CTICONTROL);
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/**
11162306a36Sopenharmony_ci * cti_disable - disable the cti module
11262306a36Sopenharmony_ci * @cti: cti instance
11362306a36Sopenharmony_ci *
11462306a36Sopenharmony_ci * enable the cti module
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_cistatic inline void cti_disable(struct cti *cti)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	__raw_writel(0, cti->base + CTICONTROL);
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci/**
12262306a36Sopenharmony_ci * cti_irq_ack - clear the cti irq
12362306a36Sopenharmony_ci * @cti: cti instance
12462306a36Sopenharmony_ci *
12562306a36Sopenharmony_ci * clear the cti irq
12662306a36Sopenharmony_ci */
12762306a36Sopenharmony_cistatic inline void cti_irq_ack(struct cti *cti)
12862306a36Sopenharmony_ci{
12962306a36Sopenharmony_ci	void __iomem *base = cti->base;
13062306a36Sopenharmony_ci	unsigned long val;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	val = __raw_readl(base + CTIINTACK);
13362306a36Sopenharmony_ci	val |= BIT(cti->trig_out_for_irq);
13462306a36Sopenharmony_ci	__raw_writel(val, base + CTIINTACK);
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci/**
13862306a36Sopenharmony_ci * cti_unlock - unlock cti module
13962306a36Sopenharmony_ci * @cti: cti instance
14062306a36Sopenharmony_ci *
14162306a36Sopenharmony_ci * unlock the cti module, or else any writes to the cti
14262306a36Sopenharmony_ci * module is not allowed.
14362306a36Sopenharmony_ci */
14462306a36Sopenharmony_cistatic inline void cti_unlock(struct cti *cti)
14562306a36Sopenharmony_ci{
14662306a36Sopenharmony_ci	__raw_writel(CS_LAR_KEY, cti->base + LOCKACCESS);
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci/**
15062306a36Sopenharmony_ci * cti_lock - lock cti module
15162306a36Sopenharmony_ci * @cti: cti instance
15262306a36Sopenharmony_ci *
15362306a36Sopenharmony_ci * lock the cti module, so any writes to the cti
15462306a36Sopenharmony_ci * module will be not allowed.
15562306a36Sopenharmony_ci */
15662306a36Sopenharmony_cistatic inline void cti_lock(struct cti *cti)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	__raw_writel(~CS_LAR_KEY, cti->base + LOCKACCESS);
15962306a36Sopenharmony_ci}
16062306a36Sopenharmony_ci#endif
161