/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
 *
 * Copyright (c) 2023 MediaTek Inc.
 *
 */

#ifndef _EMI_PLT_H_
#define _EMI_PLT_H_

/*****************************************************************************
 *  EMI Reg Definiations
 *****************************************************************************/
#define EMI_REG_BASE_MAPPED         (emi_base_remap_addr)

#define REG_EMI_BMEN	  (EMI_REG_BASE_MAPPED + 0x400)
#define REG_EMI_BSTP	  (EMI_REG_BASE_MAPPED + 0x404)
#define REG_EMI_MSEL	  (EMI_REG_BASE_MAPPED + 0x440)
#define REG_EMI_MSEL2	  (EMI_REG_BASE_MAPPED + 0x468)
#define REG_EMI_MSEL3	  (EMI_REG_BASE_MAPPED + 0x470)
#define REG_EMI_MSEL4	  (EMI_REG_BASE_MAPPED + 0x478)

#define REG_EMI_CONM      (EMI_REG_BASE_MAPPED + 0x060)
#define REG_EMI_CONN      (EMI_REG_BASE_MAPPED + 0x068)

#define REG_EMI_BMEN1	  (EMI_REG_BASE_MAPPED + 0x4e0)
#define REG_EMI_BMEN2	  (EMI_REG_BASE_MAPPED + 0x4e8)
#define REG_EMI_BMRW0     (EMI_REG_BASE_MAPPED + 0x4f8)

#define REG_EMI_EMITYPE1  (EMI_REG_BASE_MAPPED + 0x500)
#define REG_EMI_EMITYPE2  (EMI_REG_BASE_MAPPED + 0x508)
#define REG_EMI_EMITYPE3  (EMI_REG_BASE_MAPPED + 0x510)
#define REG_EMI_EMITYPE4  (EMI_REG_BASE_MAPPED + 0x518)
#define REG_EMI_EMITYPE5  (EMI_REG_BASE_MAPPED + 0x520)
#define REG_EMI_EMITYPE6  (EMI_REG_BASE_MAPPED + 0x528)
#define REG_EMI_EMITYPE7  (EMI_REG_BASE_MAPPED + 0x530)
#define REG_EMI_EMITYPE8  (EMI_REG_BASE_MAPPED + 0x538)

#define REG_EMI_EMITYPE9  (EMI_REG_BASE_MAPPED + 0x540)
#define REG_EMI_EMITYPE10 (EMI_REG_BASE_MAPPED + 0x548)
#define REG_EMI_EMITYPE11 (EMI_REG_BASE_MAPPED + 0x550)
#define REG_EMI_EMITYPE12 (EMI_REG_BASE_MAPPED + 0x558)
#define REG_EMI_EMITYPE13 (EMI_REG_BASE_MAPPED + 0x560)
#define REG_EMI_EMITYPE14 (EMI_REG_BASE_MAPPED + 0x568)
#define REG_EMI_EMITYPE15 (EMI_REG_BASE_MAPPED + 0x570)
#define REG_EMI_EMITYPE16 (EMI_REG_BASE_MAPPED + 0x578)

#define REG_EMI_EMITYPE17 (EMI_REG_BASE_MAPPED + 0x580)
#define REG_EMI_EMITYPE18 (EMI_REG_BASE_MAPPED + 0x588)
#define REG_EMI_EMITYPE19 (EMI_REG_BASE_MAPPED + 0x590)
#define REG_EMI_EMITYPE20 (EMI_REG_BASE_MAPPED + 0x598)
#define REG_EMI_EMITYPE21 (EMI_REG_BASE_MAPPED + 0x5a0)

#define REG_EMI_WACT      (EMI_REG_BASE_MAPPED + 0x420)

#define REG_EMI_TSCT      (EMI_REG_BASE_MAPPED + 0x418)
#define REG_EMI_TSCT2     (EMI_REG_BASE_MAPPED + 0x448)
#define REG_EMI_TSCT3     (EMI_REG_BASE_MAPPED + 0x450)


#define REG_EMI_WSCT      (EMI_REG_BASE_MAPPED + 0x428)
#define REG_EMI_WSCT2     (EMI_REG_BASE_MAPPED + 0x458)
#define REG_EMI_WSCT3     (EMI_REG_BASE_MAPPED + 0x460)
#define REG_EMI_WSCT4     (EMI_REG_BASE_MAPPED + 0x464)


#define REG_EMI_BMID0     (EMI_REG_BASE_MAPPED + 0x4b0)
#define REG_EMI_BMID1     (EMI_REG_BASE_MAPPED + 0x4b4)
#define REG_EMI_BMID2     (EMI_REG_BASE_MAPPED + 0x4b8)
#define REG_EMI_BMID3     (EMI_REG_BASE_MAPPED + 0x4bc)
#define REG_EMI_BMID4     (EMI_REG_BASE_MAPPED + 0x4c0)
#define REG_EMI_BMID5     (EMI_REG_BASE_MAPPED + 0x4c4)
#define REG_EMI_BMID6     (EMI_REG_BASE_MAPPED + 0x5c8)
#define REG_EMI_BMID7     (EMI_REG_BASE_MAPPED + 0x5cc)
#define REG_EMI_BMID8     (EMI_REG_BASE_MAPPED + 0x5d0)
#define REG_EMI_BMID9     (EMI_REG_BASE_MAPPED + 0x5d4)
#define REG_EMI_BMID10    (EMI_REG_BASE_MAPPED + 0x5d8)

#define REG_EMI_TTYPE1	(EMI_REG_BASE_MAPPED + 0x500)
#define REG_EMI_TTYPE9	(EMI_REG_BASE_MAPPED + 0x540)
#define REG_EMI_TTYPE_LAT(p)	(REG_EMI_TTYPE1 + ((p) * 0x8))
#define REG_EMI_TTYPE_TRANS(p)	(REG_EMI_TTYPE9 + ((p) * 0x8))

#define REG_EMI_DBWA    (EMI_REG_BASE_MAPPED + 0xF00)
#define REG_EMI_DBWB    (EMI_REG_BASE_MAPPED + 0xF04)
#define REG_EMI_DBWC    (EMI_REG_BASE_MAPPED + 0xF08)
#define REG_EMI_DBWD    (EMI_REG_BASE_MAPPED + 0xF0C)
#define REG_EMI_DBWE    (EMI_REG_BASE_MAPPED + 0xF10)
#define REG_EMI_DBWF    (EMI_REG_BASE_MAPPED + 0xF14)

#define REG_EMI_DBWG    (EMI_REG_BASE_MAPPED + 0xF18)
#define REG_EMI_DBWH    (EMI_REG_BASE_MAPPED + 0xF1C)

#define REG_EMI_DBWA_2ND    (EMI_REG_BASE_MAPPED + 0xF2C)
#define REG_EMI_DBWB_2ND    (EMI_REG_BASE_MAPPED + 0xF30)
#define REG_EMI_DBWC_2ND    (EMI_REG_BASE_MAPPED + 0xF34)
#define REG_EMI_DBWD_2ND    (EMI_REG_BASE_MAPPED + 0xF38)
#define REG_EMI_DBWE_2ND    (EMI_REG_BASE_MAPPED + 0xF3C)
#define REG_EMI_DBWF_2ND    (EMI_REG_BASE_MAPPED + 0xF40)

/* EMI_BMEN Bit Definiations */
#define EMI_BIT(bit)        (1U << (bit))
#define BUS_MON_EN          EMI_BIT(0)
#define BUS_MON_PAUSE       EMI_BIT(1)
#define BUS_MON_IDLE        EMI_BIT(3)
#define EMI_BMEN			(0x400)
#define EMI_MSEL			(0x440)
#define	EMI_MSEL2			(0x468)

/* BIT operation */
#define DBW0_HPRI_DIS		(2)
#define DBW0_WCMD_GNT_SEL	(1)
#define DBW0_RCMD_GNT_SEL	(0)

#define HPRI_SEL_HIGH		(28)
#define HPRI_SEL_FLUSH		(29)
#define HPRI_SEL_PREULTRA	(30)
#define HPRI_SEL_ULTRA		(31)

#define BUS_MON_R		(4)
#define BUS_MON_W		(5)
#define DBW0_SEL_MASTER_M0	(8)
#define DBW0_SEL_MASTER_M1	(9)
#define DBW0_SEL_MASTER_M2	(10)
#define DBW0_SEL_MASTER_M3	(11)
#define DBW0_SEL_MASTER_M4	(12)
#define DBW0_SEL_MASTER_M5	(13)
#define DBW0_SEL_MASTER_M6	(14)
#define DBW0_SEL_MASTER_M7	(15)
#define BMEN_LAT_CNT_SEL	(25)
/*****************************************************************************
 *  BM MASTER and Transaction Type Definiations
 *****************************************************************************/
#define BM_MASTER_M0            (0x01)
#define BM_MASTER_M1            (0x02)
#define BM_MASTER_M2            (0x04)
#define BM_MASTER_M3            (0x08)
#define BM_MASTER_M4            (0x10)
#define BM_MASTER_M5            (0x20)
#define BM_MASTER_M6            (0x40)
#define BM_MASTER_M7            (0x80)
#define BM_MASTER_ALL           (0xFF)

#define MASK_MASTER     0xFF
#define MASK_TRANS_TYPE 0xFF

#define LOW_16BIT		GENMASK(15, 0)
#define LOW_32BIT		GENMASK(31, 0)

#define NSEC_PER_USEC		1000L

#define bw_setbit(offset, flag, reg)					\
({									\
	typeof(offset) _offset = (offset);				\
	typeof(flag) _flag = (flag);					\
	typeof(reg) _reg = (reg);					\
	(_flag) ?							\
	writel_relaxed((readw_relaxed(_reg) | (1 << _offset)), _reg) :	\
	writel_relaxed((readw_relaxed(_reg) & ~(1 << _offset)), _reg);	\
})									\

#define	bw_div(Divisor, Dividend) ({				\
	u64 div_tmp;						\
	u32  __maybe_unused rem_tmp;				\
	div_tmp = Divisor;					\
	if (Dividend)						\
		rem_tmp = do_div((div_tmp), (Dividend));	\
	((!Dividend) ? 0 : div_tmp);				\
})

#define PERMILLAGE_ALIGN(numer)		bw_div((numer), (1000))
#define DW2BYTES(value)			(value * 8)
#define DCM_BITMASK			(0xff000000)

#define EMI_CEN_DRV		0
#define EMI_CHN_DRV		1
#define SMI_COMMON_DRV		2
#define SMI_LARB_DRV		3
#define EMI_DISPATCH_DRV	4
#define EFFI_MONITOR_DRV	5
#define CPU_PRI_DRV		6
#define MIU2GMC_DRV		7

#define MAX_DEV_NAME_LEN		15

#define EMI_0		(0)
#define EMI_1		(1)
#define EMI_2		(2)

enum {
	BM_TRANS_TYPE_1BEAT = 0x0,
	BM_TRANS_TYPE_2BEAT,
	BM_TRANS_TYPE_3BEAT,
	BM_TRANS_TYPE_4BEAT,
	BM_TRANS_TYPE_5BEAT,
	BM_TRANS_TYPE_6BEAT,
	BM_TRANS_TYPE_7BEAT,
	BM_TRANS_TYPE_8BEAT,
	BM_TRANS_TYPE_9BEAT,
	BM_TRANS_TYPE_10BEAT,
	BM_TRANS_TYPE_11BEAT,
	BM_TRANS_TYPE_12BEAT,
	BM_TRANS_TYPE_13BEAT,
	BM_TRANS_TYPE_14BEAT,
	BM_TRANS_TYPE_15BEAT,
	BM_TRANS_TYPE_16BEAT,
	BM_TRANS_TYPE_1Byte = 0 << 4,
	BM_TRANS_TYPE_2Byte = 1 << 4,
	BM_TRANS_TYPE_4Byte = 2 << 4,
	BM_TRANS_TYPE_8Byte = 3 << 4,
	BM_TRANS_TYPE_16Byte = 4 << 4,
	BM_TRANS_TYPE_32Byte = 5 << 4,
	BM_TRANS_TYPE_BURST_WRAP = 0 << 7,
	BM_TRANS_TYPE_BURST_INCR = 1 << 7
};


/*****************************************************************************
 *  EMI function Definiations
 *****************************************************************************/
enum emibm_type {
	EMIBM_TOTAL,
	EMIBM_0,
	EMIBM_1,
	EMIBM_2,
	EMIBM_3,
	EMIBM_4,
	EMIBM_5,
	NR_EMIBM_TYPE
};

void dramc_dcm_enable(bool enable);
void emi_mon_init(void);
void emi_mon_start(void);
void emi_mon_clear(void);
void emi_counter_enable(bool enable);
void emi_counter_pause(bool enable);
void emi_port_mon_select(int chan_idx);
u32 emi_pmu_read_counter(int cfg);
void emi_mon_restart(void);
extern void __iomem *emi_base_remap_addr;

#endif
