1/*
2 * Copyright 2016, General Dynamics C4 Systems
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#pragma once
8
9#include <config.h>
10
11#ifdef CONFIG_TK1_SMMU
12
13#include <types.h>
14#include <plat/machine/hardware_gen.h>
15
16#define IOASID_SIZE_BITS    7
17
18/* The SystemMMU control registers are part of memory controller */
19
20typedef struct {
21    uint32_t    intstatus;                  /* 0x00     */
22    uint32_t    intmask;                    /* 0x04     */
23    uint32_t    err_status;                 /* 0x08     */
24    uint32_t    err_adr;                    /* 0x0c     */
25    uint32_t    smmu_config;                /* 0x10     */
26    uint32_t    smmu_tlb_config;            /* 0x14     */
27    uint32_t    smmu_ptc_config;            /* 0x18     */
28    uint32_t    smmu_ptb_asid;              /* 0x1c     */
29    uint32_t    smmu_ptb_data;              /* 0x20     */
30    uint32_t    reserved0;                  /* 0x24     */
31    uint32_t    reserved1;                  /* 0x28     */
32    uint32_t    reserved2;                  /* 0x2c     */
33    uint32_t    smmu_tlb_flush;             /* 0x30     */
34    uint32_t    smmu_ptc_flush;             /* 0x34     */
35    uint32_t    reserved3[124];
36    uint32_t    smmu_translation_enable_0;  /* 0x228    */
37    uint32_t    smmu_translation_enable_1;  /* 0x22c    */
38    uint32_t    smmu_translation_enable_2;  /* 0x230    */
39    uint32_t    smmu_translation_enable_3;  /* 0x234    */
40    uint32_t    smmu_afi_asid;              /* 0x238    */
41    uint32_t    smmu_avpc_asid;             /* 0x23c    */
42    uint32_t    smmu_dc_asid;               /* 0x240    */
43    uint32_t    smmu_dcb_asid;              /* 0x244    */
44    uint32_t    reserved4;                  /* 0x248    */
45    uint32_t    reserved5;                  /* 0x24c    */
46    uint32_t    smmu_hc_asid;               /* 0x250    */
47    uint32_t    smmu_hda_asid;              /* 0x254    */
48    uint32_t    smmu_isp2_asid;             /* 0x258    */
49    uint32_t    reserved6;                  /* 0x25c    */
50    uint32_t    reserved7;                  /* 0x260    */
51    uint32_t    smmu_msenc_asid;            /* 0x264    */
52    uint32_t    smmu_nv_asid;               /* 0x268    */
53    uint32_t    smmu_nv2_asid;              /* 0x26c    */
54    uint32_t    smmu_ppcs_asid;             /* 0x270    */
55    uint32_t    smmu_sata_asid;             /* 0x274    */
56    uint32_t    reserved7_1;                /* 0x278    */
57    uint32_t    smmu_vde_asid;              /* 0x27c    */
58    uint32_t    smmu_vi_asid;               /* 0x280    */
59    uint32_t    smmu_vic_asid;              /* 0x284    */
60    uint32_t    smmu_xusb_host_asid;        /* 0x288    */
61    uint32_t    smmu_xusb_dev_asid;         /* 0x28c    */
62    uint32_t    reserved8;                  /* 0x290    */
63    uint32_t    smmu_tsec_asid;             /* 0x294    */
64    uint32_t    smmu_ppcs1_asid;            /* 0x298    */
65    uint32_t    reserved9[217];
66    uint32_t    smmu_tlb_set_sel_mask;      /* 0x600    */
67    uint32_t    reserved10[237];
68    uint32_t    smmu_ptc_flush_1;           /* 0x9b8    */
69    uint32_t    reserved11[51];
70    uint32_t    smmu_dc1_asid;              /* 0xa88    */
71    uint32_t    reserved12;                 /* 0xa8c    */
72    uint32_t    reserved13;                 /* 0xa90    */
73    uint32_t    smmu_sdmmc1a_asid;          /* 0xa94    */
74    uint32_t    smmu_sdmmc2a_asid;          /* 0xa98    */
75    uint32_t    smmu_sdmmc3a_asid;          /* 0xa9c    */
76    uint32_t    smmu_sdmmc4a_asid;          /* 0xaa0    */
77    uint32_t    smmu_isp2b_asid;            /* 0xaa4    */
78    uint32_t    smmu_gpu_asid;              /* 0xaa8    */
79    uint32_t    smmu_gpub_asid;             /* 0xaac    */
80    uint32_t    smmu_ppcs2_asid;            /* 0xab0    */
81} tk1_mc_regs_t;
82
83/* we start to allocate IO ASIDs from 1, and each module's ASID
84 * is fixed (i.e. users are not allowed to dynamically allocate
85 * ASIDs and assign them to devices).
86 */
87#define SMMU_FIRST_ASID     1
88#define SMMU_AFI_ASID       1
89#define SMMU_AVPC_ASID      2
90#define SMMU_DC_ASID        3
91#define SMMU_DCB_ASID       4
92#define SMMU_HC_ASID        5
93#define SMMU_HDA_ASID       6
94#define SMMU_ISP2_ASID      7
95#define SMMU_MSENC_ASID     8
96#define SMMU_NV_ASID        9
97#define SMMU_NV2_ASID       10
98#define SMMU_PPCS_ASID      11
99#define SMMU_SATA_ASID      12
100#define SMMU_VDE_ASID       13
101#define SMMU_VI_ASID        14
102#define SMMU_VIC_ASID       15
103#define SMMU_XUSB_HOST_ASID 16
104#define SMMU_XUSB_DEV_ASID  17
105#define SMMU_TSEC_ASID      18
106#define SMMU_PPCS1_ASID     19
107#define SMMU_DC1_ASID       20
108#define SMMU_SDMMC1A_ASID   21
109#define SMMU_SDMMC2A_ASID   22
110#define SMMU_SDMMC3A_ASID   23
111#define SMMU_SDMMC4A_ASID   24
112#define SMMU_ISP2B_ASID     25
113#define SMMU_GPU_ASID       26
114#define SMMU_GPUB_ASID      27
115#define SMMU_PPCS2_ASID     28
116#define SMMU_LAST_ASID      28
117
118#define ARM_PLAT_NUM_SMMU   28
119
120#define SMMU_PD_INDEX_BITS        12
121#define SMMU_PT_INDEX_BITS        12
122
123#define SMMU_IOPD_INDEX_MASK    0xffc00000
124#define SMMU_IOPD_INDEX_SHIFT   22
125#define SMMU_IOPT_INDEX_MASK    0x3ff000
126#define SMMU_IOPT_INDEX_SHIFT   12
127
128inline static uint32_t plat_smmu_iopd_index(word_t io_address)
129{
130    uint32_t ret = (io_address & SMMU_IOPD_INDEX_MASK) >> SMMU_IOPD_INDEX_SHIFT;
131    return ret;
132}
133
134inline static uint32_t plat_smmu_iopt_index(word_t io_address)
135{
136    uint32_t ret = (io_address & SMMU_IOPT_INDEX_MASK) >> SMMU_IOPT_INDEX_SHIFT;
137    return ret;
138}
139
140inline static uint32_t plat_smmu_get_asid_by_module_id(uint32_t mid)
141{
142    if (mid < SMMU_FIRST_ASID || mid > SMMU_LAST_ASID) {
143        return asidInvalid;
144    }
145
146    /* we have one-to-one mapping from module id to ASID */
147    return mid;
148
149}
150
151int plat_smmu_init(void);
152
153void plat_smmu_tlb_flush_all(void);
154
155void plat_smmu_ptc_flush_all(void);
156
157iopde_t *plat_smmu_lookup_iopd_by_asid(uint32_t asid);
158void plat_smmu_handle_interrupt(void);
159
160#else /* !CONFIG_TK1_SMMU */
161
162/* dummy functions */
163static inline void plat_smmu_handle_interrupt(void)
164{
165    return;
166}
167
168#endif /* CONFIG_TK1_SMMU */
169
170