/* SPDX-License-Identifier: GPL-2.0 */

/* Renesas Ethernet-TSN device driver
 *
 * Copyright (C) 2022 Renesas Electronics Corporation
 * Copyright (C) 2023 Niklas Söderlund <niklas.soderlund@ragnatech.se>
 */

#ifndef __RTSN_H__
#define __RTSN_H__

#include <linux/types.h>

#define AXIBMI	0x0000
#define TSNMHD	0x1000
#define RMSO	0x2000
#define RMRO	0x3800

enum rtsn_reg {
	AXIWC		= AXIBMI + 0x0000,
	AXIRC		= AXIBMI + 0x0004,
	TDPC0		= AXIBMI + 0x0010,
	TFT		= AXIBMI + 0x0090,
	TATLS0		= AXIBMI + 0x00a0,
	TATLS1		= AXIBMI + 0x00a4,
	TATLR		= AXIBMI + 0x00a8,
	RATLS0		= AXIBMI + 0x00b0,
	RATLS1		= AXIBMI + 0x00b4,
	RATLR		= AXIBMI + 0x00b8,
	TSA0		= AXIBMI + 0x00c0,
	TSS0		= AXIBMI + 0x00c4,
	TRCR0		= AXIBMI + 0x0140,
	RIDAUAS0	= AXIBMI + 0x0180,
	RR		= AXIBMI + 0x0200,
	TATS		= AXIBMI + 0x0210,
	TATSR0		= AXIBMI + 0x0214,
	TATSR1		= AXIBMI + 0x0218,
	TATSR2		= AXIBMI + 0x021c,
	RATS		= AXIBMI + 0x0220,
	RATSR0		= AXIBMI + 0x0224,
	RATSR1		= AXIBMI + 0x0228,
	RATSR2		= AXIBMI + 0x022c,
	RIDASM0		= AXIBMI + 0x0240,
	RIDASAM0	= AXIBMI + 0x0244,
	RIDACAM0	= AXIBMI + 0x0248,
	EIS0		= AXIBMI + 0x0300,
	EIE0		= AXIBMI + 0x0304,
	EID0		= AXIBMI + 0x0308,
	EIS1		= AXIBMI + 0x0310,
	EIE1		= AXIBMI + 0x0314,
	EID1		= AXIBMI + 0x0318,
	TCEIS0		= AXIBMI + 0x0340,
	TCEIE0		= AXIBMI + 0x0344,
	TCEID0		= AXIBMI + 0x0348,
	RFSEIS0		= AXIBMI + 0x04c0,
	RFSEIE0		= AXIBMI + 0x04c4,
	RFSEID0		= AXIBMI + 0x04c8,
	RFEIS0		= AXIBMI + 0x0540,
	RFEIE0		= AXIBMI + 0x0544,
	RFEID0		= AXIBMI + 0x0548,
	RCEIS0		= AXIBMI + 0x05c0,
	RCEIE0		= AXIBMI + 0x05c4,
	RCEID0		= AXIBMI + 0x05c8,
	RIDAOIS		= AXIBMI + 0x0640,
	RIDAOIE		= AXIBMI + 0x0644,
	RIDAOID		= AXIBMI + 0x0648,
	TSFEIS		= AXIBMI + 0x06c0,
	TSFEIE		= AXIBMI + 0x06c4,
	TSFEID		= AXIBMI + 0x06c8,
	TSCEIS		= AXIBMI + 0x06d0,
	TSCEIE		= AXIBMI + 0x06d4,
	TSCEID		= AXIBMI + 0x06d8,
	DIS		= AXIBMI + 0x0b00,
	DIE		= AXIBMI + 0x0b04,
	DID		= AXIBMI + 0x0b08,
	TDIS0		= AXIBMI + 0x0b10,
	TDIE0		= AXIBMI + 0x0b14,
	TDID0		= AXIBMI + 0x0b18,
	RDIS0		= AXIBMI + 0x0b90,
	RDIE0		= AXIBMI + 0x0b94,
	RDID0		= AXIBMI + 0x0b98,
	TSDIS		= AXIBMI + 0x0c10,
	TSDIE		= AXIBMI + 0x0c14,
	TSDID		= AXIBMI + 0x0c18,
	GPOUT		= AXIBMI + 0x6000,

	OCR		= TSNMHD + 0x0000,
	OSR		= TSNMHD + 0x0004,
	SWR		= TSNMHD + 0x0008,
	SIS		= TSNMHD + 0x000c,
	GIS		= TSNMHD + 0x0010,
	GIE		= TSNMHD + 0x0014,
	GID		= TSNMHD + 0x0018,
	TIS1		= TSNMHD + 0x0020,
	TIE1		= TSNMHD + 0x0024,
	TID1		= TSNMHD + 0x0028,
	TIS2		= TSNMHD + 0x0030,
	TIE2		= TSNMHD + 0x0034,
	TID2		= TSNMHD + 0x0038,
	RIS		= TSNMHD + 0x0040,
	RIE		= TSNMHD + 0x0044,
	RID		= TSNMHD + 0x0048,
	TGC1		= TSNMHD + 0x0050,
	TGC2		= TSNMHD + 0x0054,
	TFS0		= TSNMHD + 0x0060,
	TCF0		= TSNMHD + 0x0070,
	TCR1		= TSNMHD + 0x0080,
	TCR2		= TSNMHD + 0x0084,
	TCR3		= TSNMHD + 0x0088,
	TCR4		= TSNMHD + 0x008c,
	TMS0		= TSNMHD + 0x0090,
	TSR1		= TSNMHD + 0x00b0,
	TSR2		= TSNMHD + 0x00b4,
	TSR3		= TSNMHD + 0x00b8,
	TSR4		= TSNMHD + 0x00bc,
	TSR5		= TSNMHD + 0x00c0,
	RGC		= TSNMHD + 0x00d0,
	RDFCR		= TSNMHD + 0x00d4,
	RCFCR		= TSNMHD + 0x00d8,
	REFCNCR		= TSNMHD + 0x00dc,
	RSR1		= TSNMHD + 0x00e0,
	RSR2		= TSNMHD + 0x00e4,
	RSR3		= TSNMHD + 0x00e8,
	TCIS		= TSNMHD + 0x01e0,
	TCIE		= TSNMHD + 0x01e4,
	TCID		= TSNMHD + 0x01e8,
	TPTPC		= TSNMHD + 0x01f0,
	TTML		= TSNMHD + 0x01f4,
	TTJ		= TSNMHD + 0x01f8,
	TCC		= TSNMHD + 0x0200,
	TCS		= TSNMHD + 0x0204,
	TGS		= TSNMHD + 0x020c,
	TACST0		= TSNMHD + 0x0210,
	TACST1		= TSNMHD + 0x0214,
	TACST2		= TSNMHD + 0x0218,
	TALIT0		= TSNMHD + 0x0220,
	TALIT1		= TSNMHD + 0x0224,
	TALIT2		= TSNMHD + 0x0228,
	TAEN0		= TSNMHD + 0x0230,
	TAEN1		= TSNMHD + 0x0234,
	TASFE		= TSNMHD + 0x0240,
	TACLL0		= TSNMHD + 0x0250,
	TACLL1		= TSNMHD + 0x0254,
	TACLL2		= TSNMHD + 0x0258,
	CACC		= TSNMHD + 0x0260,
	CCS		= TSNMHD + 0x0264,
	CAIV0		= TSNMHD + 0x0270,
	CAUL0		= TSNMHD + 0x0290,
	TOCST0		= TSNMHD + 0x0300,
	TOCST1		= TSNMHD + 0x0304,
	TOCST2		= TSNMHD + 0x0308,
	TOLIT0		= TSNMHD + 0x0310,
	TOLIT1		= TSNMHD + 0x0314,
	TOLIT2		= TSNMHD + 0x0318,
	TOEN0		= TSNMHD + 0x0320,
	TOEN1		= TSNMHD + 0x0324,
	TOSFE		= TSNMHD + 0x0330,
	TCLR0		= TSNMHD + 0x0340,
	TCLR1		= TSNMHD + 0x0344,
	TCLR2		= TSNMHD + 0x0348,
	TSMS		= TSNMHD + 0x0350,
	COCC		= TSNMHD + 0x0360,
	COIV0		= TSNMHD + 0x03b0,
	COUL0		= TSNMHD + 0x03d0,
	QSTMACU0	= TSNMHD + 0x0400,
	QSTMACD0	= TSNMHD + 0x0404,
	QSTMAMU0	= TSNMHD + 0x0408,
	QSTMAMD0	= TSNMHD + 0x040c,
	QSFTVL0		= TSNMHD + 0x0410,
	QSFTVLM0	= TSNMHD + 0x0414,
	QSFTMSD0	= TSNMHD + 0x0418,
	QSFTGMI0	= TSNMHD + 0x041c,
	QSFTLS		= TSNMHD + 0x0600,
	QSFTLIS		= TSNMHD + 0x0604,
	QSFTLIE		= TSNMHD + 0x0608,
	QSFTLID		= TSNMHD + 0x060c,
	QSMSMC		= TSNMHD + 0x0610,
	QSGTMC		= TSNMHD + 0x0614,
	QSEIS		= TSNMHD + 0x0618,
	QSEIE		= TSNMHD + 0x061c,
	QSEID		= TSNMHD + 0x0620,
	QGACST0		= TSNMHD + 0x0630,
	QGACST1		= TSNMHD + 0x0634,
	QGACST2		= TSNMHD + 0x0638,
	QGALIT1		= TSNMHD + 0x0640,
	QGALIT2		= TSNMHD + 0x0644,
	QGAEN0		= TSNMHD + 0x0648,
	QGAEN1		= TSNMHD + 0x074c,
	QGIGS		= TSNMHD + 0x0650,
	QGGC		= TSNMHD + 0x0654,
	QGATL0		= TSNMHD + 0x0664,
	QGATL1		= TSNMHD + 0x0668,
	QGATL2		= TSNMHD + 0x066c,
	QGOCST0		= TSNMHD + 0x0670,
	QGOCST1		= TSNMHD + 0x0674,
	QGOCST2		= TSNMHD + 0x0678,
	QGOLIT0		= TSNMHD + 0x067c,
	QGOLIT1		= TSNMHD + 0x0680,
	QGOLIT2		= TSNMHD + 0x0684,
	QGOEN0		= TSNMHD + 0x0688,
	QGOEN1		= TSNMHD + 0x068c,
	QGTRO		= TSNMHD + 0x0690,
	QGTR1		= TSNMHD + 0x0694,
	QGTR2		= TSNMHD + 0x0698,
	QGFSMS		= TSNMHD + 0x069c,
	QTMIS		= TSNMHD + 0x06e0,
	QTMIE		= TSNMHD + 0x06e4,
	QTMID		= TSNMHD + 0x06e8,
	QMEC		= TSNMHD + 0x0700,
	QMMC		= TSNMHD + 0x0704,
	QRFDC		= TSNMHD + 0x0708,
	QYFDC		= TSNMHD + 0x070c,
	QVTCMC0		= TSNMHD + 0x0710,
	QMCBSC0		= TSNMHD + 0x0750,
	QMCIRC0		= TSNMHD + 0x0790,
	QMEBSC0		= TSNMHD + 0x07d0,
	QMEIRC0		= TSNMHD + 0x0710,
	QMCFC		= TSNMHD + 0x0850,
	QMEIS		= TSNMHD + 0x0860,
	QMEIE		= TSNMHD + 0x0864,
	QMEID		= TSNMHD + 0x086c,
	QSMFC0		= TSNMHD + 0x0870,
	QMSPPC0		= TSNMHD + 0x08b0,
	QMSRPC0		= TSNMHD + 0x08f0,
	QGPPC0		= TSNMHD + 0x0930,
	QGRPC0		= TSNMHD + 0x0950,
	QMDPC0		= TSNMHD + 0x0970,
	QMGPC0		= TSNMHD + 0x09b0,
	QMYPC0		= TSNMHD + 0x09f0,
	QMRPC0		= TSNMHD + 0x0a30,
	MQSTMACU	= TSNMHD + 0x0a70,
	MQSTMACD	= TSNMHD + 0x0a74,
	MQSTMAMU	= TSNMHD + 0x0a78,
	MQSTMAMD	= TSNMHD + 0x0a7c,
	MQSFTVL		= TSNMHD + 0x0a80,
	MQSFTVLM	= TSNMHD + 0x0a84,
	MQSFTMSD	= TSNMHD + 0x0a88,
	MQSFTGMI	= TSNMHD + 0x0a8c,

	CFCR0		= RMSO + 0x0800,
	FMSCR		= RMSO + 0x0c10,

	MMC		= RMRO + 0x0000,
	MPSM		= RMRO + 0x0010,
	MPIC		= RMRO + 0x0014,
	MTFFC		= RMRO + 0x0020,
	MTPFC		= RMRO + 0x0024,
	MTATC0		= RMRO + 0x0040,
	MRGC		= RMRO + 0x0080,
	MRMAC0		= RMRO + 0x0084,
	MRMAC1		= RMRO + 0x0088,
	MRAFC		= RMRO + 0x008c,
	MRSCE		= RMRO + 0x0090,
	MRSCP		= RMRO + 0x0094,
	MRSCC		= RMRO + 0x0098,
	MRFSCE		= RMRO + 0x009c,
	MRFSCP		= RMRO + 0x00a0,
	MTRC		= RMRO + 0x00a4,
	MPFC		= RMRO + 0x0100,
	MLVC		= RMRO + 0x0340,
	MEEEC		= RMRO + 0x0350,
	MLBC		= RMRO + 0x0360,
	MGMR		= RMRO + 0x0400,
	MMPFTCT		= RMRO + 0x0410,
	MAPFTCT		= RMRO + 0x0414,
	MPFRCT		= RMRO + 0x0418,
	MFCICT		= RMRO + 0x041c,
	MEEECT		= RMRO + 0x0420,
	MEIS		= RMRO + 0x0500,
	MEIE		= RMRO + 0x0504,
	MEID		= RMRO + 0x0508,
	MMIS0		= RMRO + 0x0510,
	MMIE0		= RMRO + 0x0514,
	MMID0		= RMRO + 0x0518,
	MMIS1		= RMRO + 0x0520,
	MMIE1		= RMRO + 0x0524,
	MMID1		= RMRO + 0x0528,
	MMIS2		= RMRO + 0x0530,
	MMIE2		= RMRO + 0x0534,
	MMID2		= RMRO + 0x0538,
	MXMS		= RMRO + 0x0600,

};

/* AXIBMI */
#define RR_RATRR		BIT(0)
#define RR_TATRR		BIT(1)
#define RR_RST			(RR_RATRR | RR_TATRR)
#define RR_RST_COMPLETE		0x03

#define AXIWC_DEFAULT		0xffff
#define AXIRC_DEFAULT		0xffff

#define TATLS0_TEDE		BIT(1)
#define TATLS0_TATEN_SHIFT	24
#define TATLS0_TATEN(n)		((n) << TATLS0_TATEN_SHIFT)
#define TATLR_TATL		BIT(31)

#define RATLS0_RETS		BIT(2)
#define RATLS0_REDE		BIT(3)
#define RATLS0_RATEN_SHIFT	24
#define RATLS0_RATEN(n)		((n) << RATLS0_RATEN_SHIFT)
#define RATLR_RATL		BIT(31)

#define DIE_DID_TDICX(n)	BIT((n))
#define DIE_DID_RDICX(n)	BIT((n) + 8)
#define TDIE_TDID_TDX(n)	BIT(n)
#define RDIE_RDID_RDX(n)	BIT(n)
#define TDIS_TDS(n)		BIT(n)
#define RDIS_RDS(n)		BIT(n)

/* MHD */
#define OSR_OPS			0x07
#define SWR_SWR			BIT(0)

#define TGC1_TQTM_SFM		0xff00
#define TGC1_STTV_DEFAULT	0x03

#define TMS_MFS_MAX		0x2800

/* RMAC System */
#define CFCR_SDID(n)		((n) << 16)
#define FMSCR_FMSIE(n)		((n) << 0)

/* RMAC */
#define MPIC_PIS_MASK		GENMASK(1, 0)
#define MPIC_PIS_MII		0
#define MPIC_PIS_RMII		0x01
#define MPIC_PIS_GMII		0x02
#define MPIC_PIS_RGMII		0x03
#define MPIC_LSC_SHIFT		2
#define MPIC_LSC_MASK		GENMASK(3, MPIC_LSC_SHIFT)
#define MPIC_LSC_10M		(0 << MPIC_LSC_SHIFT)
#define MPIC_LSC_100M		(0x01 << MPIC_LSC_SHIFT)
#define MPIC_LSC_1G		(0x02 << MPIC_LSC_SHIFT)
#define MPIC_PSMCS_SHIFT	16
#define MPIC_PSMCS_MASK		GENMASK(21, MPIC_PSMCS_SHIFT)
#define MPIC_PSMCS_DEFAULT	(0x0a << MPIC_PSMCS_SHIFT)
#define MPIC_PSMHT_SHIFT	24
#define MPIC_PSMHT_MASK		GENMASK(26, MPIC_PSMHT_SHIFT)
#define MPIC_PSMHT_DEFAULT	(0x07 << MPIC_PSMHT_SHIFT)

#define MLVC_PASE		BIT(8)
#define MLVC_PSE		BIT(16)
#define MLVC_PLV		BIT(17)

#define MPSM_PSME		BIT(0)
#define MPSM_PSMAD		BIT(1)
#define MPSM_PDA_SHIFT		3
#define MPSM_PDA_MASK		GENMASK(7, 3)
#define MPSM_PDA(n)		(((n) << MPSM_PDA_SHIFT) & MPSM_PDA_MASK)
#define MPSM_PRA_SHIFT		8
#define MPSM_PRA_MASK		GENMASK(12, 8)
#define MPSM_PRA(n)		(((n) << MPSM_PRA_SHIFT) & MPSM_PRA_MASK)
#define MPSM_PRD_SHIFT		16
#define MPSM_PRD_SET(n)		((n) << MPSM_PRD_SHIFT)
#define MPSM_PRD_GET(n)		((n) >> MPSM_PRD_SHIFT)

#define GPOUT_RDM		BIT(13)
#define GPOUT_TDM		BIT(14)

/* RTSN */
#define RTSN_INTERVAL_US	1000
#define RTSN_TIMEOUT_US		1000000

#define TX_NUM_CHAINS		1
#define RX_NUM_CHAINS		1

#define TX_CHAIN_SIZE		1024
#define RX_CHAIN_SIZE		1024

#define TX_CHAIN_IDX		0
#define RX_CHAIN_IDX		0

#define TX_CHAIN_ADDR_OFFSET	(sizeof(struct rtsn_desc) * TX_CHAIN_IDX)
#define RX_CHAIN_ADDR_OFFSET	(sizeof(struct rtsn_desc) * RX_CHAIN_IDX)

#define PKT_BUF_SZ		1584
#define RTSN_ALIGN		128

enum rtsn_mode {
	OCR_OPC_DISABLE,
	OCR_OPC_CONFIG,
	OCR_OPC_OPERATION,
};

/* Descriptors */
enum RX_DS_CC_BIT {
	RX_DS	= 0x0fff, /* Data size */
	RX_TR	= 0x1000, /* Truncation indication */
	RX_EI	= 0x2000, /* Error indication */
	RX_PS	= 0xc000, /* Padding selection */
};

enum TX_FS_TAGL_BIT {
	TX_DS	= 0x0fff, /* Data size */
	TX_TAGL	= 0xf000, /* Frame tag LSBs */
};

enum DIE_DT {
	/* HW/SW arbitration */
	DT_FEMPTY_IS	= 0x10,
	DT_FEMPTY_IC	= 0x20,
	DT_FEMPTY_ND	= 0x30,
	DT_FEMPTY	= 0x40,
	DT_FEMPTY_START	= 0x50,
	DT_FEMPTY_MID	= 0x60,
	DT_FEMPTY_END	= 0x70,

	/* Frame data */
	DT_FSINGLE	= 0x80,
	DT_FSTART	= 0x90,
	DT_FMID		= 0xa0,
	DT_FEND		= 0xb0,

	/* Chain control */
	DT_LEMPTY	= 0xc0,
	DT_EEMPTY	= 0xd0,
	DT_LINK		= 0xe0,
	DT_EOS		= 0xf0,

	DT_MASK		= 0xf0,
	D_DIE		= 0x08,
};

struct rtsn_desc {
	__le16 info_ds;
	__u8 info;
	u8 die_dt;
	__le32 dptr;
} __packed;

struct rtsn_ts_desc {
	__le16 info_ds;
	__u8 info;
	u8 die_dt;
	__le32 dptr;
	__le32 ts_nsec;
	__le32 ts_sec;
} __packed;

struct rtsn_ext_desc {
	__le16 info_ds;
	__u8 info;
	u8 die_dt;
	__le32 dptr;
	__le64 info1;
} __packed;

struct rtsn_ext_ts_desc {
	__le16 info_ds;
	__u8 info;
	u8 die_dt;
	__le32 dptr;
	__le64 info1;
	__le32 ts_nsec;
	__le32 ts_sec;
} __packed;

enum EXT_INFO_DS_BIT {
	TXC = 0x4000,
};

#endif
