214 lines
4.7 KiB
C
214 lines
4.7 KiB
C
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
/*
|
||
|
* Copyright (c) 2019 MediaTek Inc.
|
||
|
*/
|
||
|
|
||
|
#ifndef __M4U_HW_H__
|
||
|
#define __M4U_HW_H__
|
||
|
|
||
|
#define M4U_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M)
|
||
|
|
||
|
#define TOTAL_M4U_NUM 1
|
||
|
#define M4U_SLAVE_NUM(m4u_id) \
|
||
|
((m4u_id) ? 2 : 1) /* m4u0 has 2 slaves, iommu(m4u1) has 1 slave */
|
||
|
|
||
|
/* seq range related */
|
||
|
#define SEQ_NR_PER_MM_SLAVE 8
|
||
|
#define SEQ_NR_PER_PERI_SLAVE 0
|
||
|
|
||
|
#define M4U0_SEQ_NR (SEQ_NR_PER_MM_SLAVE * M4U_SLAVE_NUM(0))
|
||
|
#define M4U1_SEQ_NR (SEQ_NR_PER_PERI_SLAVE * M4U_SLAVE_NUM(1))
|
||
|
#define M4U_SEQ_NUM(m4u_id) ((m4u_id) ? M4U1_SEQ_NR : M4U0_SEQ_NR)
|
||
|
|
||
|
#define M4U0_MAU_NR 1
|
||
|
|
||
|
#define M4U_SEQ_ALIGN_MSK (0x100000 - 1)
|
||
|
#define M4U_SEQ_ALIGN_SIZE 0x100000
|
||
|
|
||
|
/* mau related */
|
||
|
#define MAU_NR_PER_M4U_SLAVE 1
|
||
|
|
||
|
/* smi */
|
||
|
#define SMI_LARB_NR 3
|
||
|
|
||
|
/* prog pfh dist related */
|
||
|
#define PROG_PFH_DIST 2
|
||
|
|
||
|
#define M4U0_PROG_PFH_NR (PROG_PFH_DIST)
|
||
|
#define M4U1_PROG_PFH_NR (PROG_PFH_DIST)
|
||
|
#define M4U_PROG_PFH_NUM(m4u_id) \
|
||
|
((m4u_id) ? M4U1_PROG_PFH_NR : M4U0_PROG_PFH_NR)
|
||
|
|
||
|
typedef struct _M4U_PERF_COUNT {
|
||
|
unsigned int transaction_cnt;
|
||
|
unsigned int main_tlb_miss_cnt;
|
||
|
unsigned int pfh_tlb_miss_cnt;
|
||
|
unsigned int pfh_cnt;
|
||
|
unsigned int rs_perf_cnt;
|
||
|
} M4U_PERF_COUNT;
|
||
|
|
||
|
typedef struct __mmu_tlb {
|
||
|
unsigned int tag;
|
||
|
unsigned int desc;
|
||
|
} mmu_tlb_t;
|
||
|
|
||
|
typedef struct _pfh_tlb {
|
||
|
unsigned int va;
|
||
|
unsigned int va_msk;
|
||
|
char layer;
|
||
|
char x16;
|
||
|
char sec;
|
||
|
char pfh;
|
||
|
char valid;
|
||
|
unsigned int desc[MMU_PAGE_PER_LINE];
|
||
|
int set;
|
||
|
int way;
|
||
|
unsigned int page_size;
|
||
|
unsigned int tag;
|
||
|
} mmu_pfh_tlb_t;
|
||
|
|
||
|
typedef struct {
|
||
|
char *name;
|
||
|
unsigned m4u_id : 2;
|
||
|
unsigned m4u_slave : 2;
|
||
|
unsigned larb_id : 4;
|
||
|
unsigned larb_port : 8;
|
||
|
unsigned tf_id : 12; /* 12 bits */
|
||
|
bool enable_tf;
|
||
|
m4u_reclaim_mva_callback_t *reclaim_fn;
|
||
|
void *reclaim_data;
|
||
|
m4u_fault_callback_t *fault_fn;
|
||
|
void *fault_data;
|
||
|
} m4u_port_t;
|
||
|
|
||
|
typedef struct _M4U_RANGE_DES /* sequential entry range */
|
||
|
{
|
||
|
unsigned int Enabled;
|
||
|
M4U_PORT_ID port;
|
||
|
unsigned int MVAStart;
|
||
|
unsigned int MVAEnd;
|
||
|
/* unsigned int entryCount; */
|
||
|
} M4U_RANGE_DES_T;
|
||
|
|
||
|
typedef struct _M4U_MAU_STATUS /* mau entry */
|
||
|
{
|
||
|
bool Enabled;
|
||
|
M4U_PORT_ID port;
|
||
|
unsigned int MVAStart;
|
||
|
unsigned int MVAEnd;
|
||
|
} M4U_MAU_STATUS_T;
|
||
|
|
||
|
typedef struct _M4U_PROG_DIST { /* prog pfh dist */
|
||
|
unsigned int Enabled;
|
||
|
M4U_PORT_ID port;
|
||
|
unsigned int mm_id;
|
||
|
unsigned int dir;
|
||
|
unsigned int dist;
|
||
|
unsigned int en;
|
||
|
unsigned int sel;
|
||
|
} M4U_PROG_DIST_T;
|
||
|
|
||
|
extern m4u_port_t gM4uPort[];
|
||
|
extern int gM4u_port_num;
|
||
|
|
||
|
static inline char *m4u_get_port_name(M4U_PORT_ID portID)
|
||
|
{
|
||
|
if ((portID < gM4u_port_num) && (portID >= M4U_PORT_DISP_OVL0))
|
||
|
return gM4uPort[portID].name;
|
||
|
|
||
|
return "m4u_port_unknown";
|
||
|
}
|
||
|
|
||
|
static inline int m4u_get_port_by_tf_id(int m4u_id, int tf_id)
|
||
|
{
|
||
|
int i, tf_id_old;
|
||
|
|
||
|
tf_id_old = tf_id;
|
||
|
|
||
|
if (m4u_id == 0)
|
||
|
tf_id &= F_MMU0_INT_ID_TF_MSK;
|
||
|
|
||
|
for (i = 0; i < gM4u_port_num; i++) {
|
||
|
if ((gM4uPort[i].tf_id == tf_id) &&
|
||
|
(gM4uPort[i].m4u_id == m4u_id))
|
||
|
return i;
|
||
|
}
|
||
|
M4UMSG("error: m4u_id=%d, tf_id=0x%x\n", m4u_id, tf_id_old);
|
||
|
return gM4u_port_num;
|
||
|
}
|
||
|
|
||
|
static inline int m4u_port_2_larb_port(M4U_PORT_ID port)
|
||
|
{
|
||
|
if (port >= 0 && port < M4U_PORT_UNKNOWN)
|
||
|
return gM4uPort[port].larb_port;
|
||
|
M4UMSG("%s fail, port=%d\n", __func__, port);
|
||
|
return gM4u_port_num;
|
||
|
}
|
||
|
|
||
|
static inline int m4u_port_2_larb_id(M4U_PORT_ID port)
|
||
|
{
|
||
|
if ((port < gM4u_port_num) && (port >= M4U_PORT_DISP_OVL0))
|
||
|
return gM4uPort[port].larb_id;
|
||
|
return 0xff;
|
||
|
}
|
||
|
|
||
|
static inline int larb_2_m4u_slave_id(int larb)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < gM4u_port_num; i++) {
|
||
|
if (gM4uPort[i].larb_id == larb)
|
||
|
return gM4uPort[i].m4u_slave;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static inline int m4u_port_2_m4u_id(M4U_PORT_ID port)
|
||
|
{
|
||
|
if (port >= 0 && port < gM4u_port_num)
|
||
|
return gM4uPort[port].m4u_id;
|
||
|
|
||
|
M4UMSG("%s fail, port=%d\n", __func__, port);
|
||
|
return gM4u_port_num;
|
||
|
}
|
||
|
|
||
|
static inline int m4u_port_2_m4u_slave_id(M4U_PORT_ID port)
|
||
|
{
|
||
|
if (port >= 0 && port < gM4u_port_num)
|
||
|
return gM4uPort[port].m4u_slave;
|
||
|
|
||
|
M4UMSG("%s fail, port=%d\n", __func__, port);
|
||
|
return gM4u_port_num;
|
||
|
}
|
||
|
|
||
|
static inline int larb_port_2_m4u_port(int larb, int larb_port)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < gM4u_port_num; i++) {
|
||
|
if (gM4uPort[i].larb_id == larb &&
|
||
|
gM4uPort[i].larb_port == larb_port)
|
||
|
return i;
|
||
|
}
|
||
|
/* M4UMSG("unknown larb port: larb=%d, larb_port=%d\n", larb, larb_port); */
|
||
|
return M4U_PORT_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
void m4u_print_perf_counter(int m4u_index, int m4u_slave_id, const char *msg);
|
||
|
int m4u_dump_reg(int m4u_index, unsigned int start, unsigned int end);
|
||
|
/* For build while larb0 clk has not been implemented.*/
|
||
|
static inline void smi_larb0_clock_on(void)
|
||
|
{
|
||
|
}
|
||
|
static inline void smi_larb0_clock_off(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
extern struct m4u_device *gM4uDev;
|
||
|
|
||
|
#ifdef M4U_TEE_SERVICE_ENABLE
|
||
|
extern int m4u_tee_en;
|
||
|
#endif
|
||
|
|
||
|
#endif
|