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