1 // SPDX-License-Identifier: GPL-2.0 2 3 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. 4 * Copyright (C) 2019-2023 Linaro Ltd. 5 */ 6 7 #include <linux/io.h> 8 9 #include "ipa.h" 10 #include "ipa_reg.h" 11 12 /* Is this register ID valid for the current IPA version? */ 13 static bool ipa_reg_id_valid(struct ipa *ipa, enum ipa_reg_id reg_id) 14 { 15 enum ipa_version version = ipa->version; 16 17 switch (reg_id) { 18 case FILT_ROUT_HASH_EN: 19 return version == IPA_VERSION_4_2; 20 21 case FILT_ROUT_HASH_FLUSH: 22 return version < IPA_VERSION_5_0 && version != IPA_VERSION_4_2; 23 24 case FILT_ROUT_CACHE_FLUSH: 25 case ENDP_FILTER_CACHE_CFG: 26 case ENDP_ROUTER_CACHE_CFG: 27 return version >= IPA_VERSION_5_0; 28 29 case IPA_BCR: 30 case COUNTER_CFG: 31 return version < IPA_VERSION_4_5; 32 33 case IPA_TX_CFG: 34 case FLAVOR_0: 35 case IDLE_INDICATION_CFG: 36 return version >= IPA_VERSION_3_5; 37 38 case QTIME_TIMESTAMP_CFG: 39 case TIMERS_XO_CLK_DIV_CFG: 40 case TIMERS_PULSE_GRAN_CFG: 41 return version >= IPA_VERSION_4_5; 42 43 case SRC_RSRC_GRP_45_RSRC_TYPE: 44 case DST_RSRC_GRP_45_RSRC_TYPE: 45 return version <= IPA_VERSION_3_1 || 46 version == IPA_VERSION_4_5 || 47 version == IPA_VERSION_5_0; 48 49 case SRC_RSRC_GRP_67_RSRC_TYPE: 50 case DST_RSRC_GRP_67_RSRC_TYPE: 51 return version <= IPA_VERSION_3_1 || 52 version == IPA_VERSION_5_0; 53 54 case ENDP_FILTER_ROUTER_HSH_CFG: 55 return version < IPA_VERSION_5_0 && 56 version != IPA_VERSION_4_2; 57 58 case IRQ_SUSPEND_EN: 59 case IRQ_SUSPEND_CLR: 60 return version >= IPA_VERSION_3_1; 61 62 case COMP_CFG: 63 case CLKON_CFG: 64 case ROUTE: 65 case SHARED_MEM_SIZE: 66 case QSB_MAX_WRITES: 67 case QSB_MAX_READS: 68 case STATE_AGGR_ACTIVE: 69 case LOCAL_PKT_PROC_CNTXT: 70 case AGGR_FORCE_CLOSE: 71 case SRC_RSRC_GRP_01_RSRC_TYPE: 72 case SRC_RSRC_GRP_23_RSRC_TYPE: 73 case DST_RSRC_GRP_01_RSRC_TYPE: 74 case DST_RSRC_GRP_23_RSRC_TYPE: 75 case ENDP_INIT_CTRL: 76 case ENDP_INIT_CFG: 77 case ENDP_INIT_NAT: 78 case ENDP_INIT_HDR: 79 case ENDP_INIT_HDR_EXT: 80 case ENDP_INIT_HDR_METADATA_MASK: 81 case ENDP_INIT_MODE: 82 case ENDP_INIT_AGGR: 83 case ENDP_INIT_HOL_BLOCK_EN: 84 case ENDP_INIT_HOL_BLOCK_TIMER: 85 case ENDP_INIT_DEAGGR: 86 case ENDP_INIT_RSRC_GRP: 87 case ENDP_INIT_SEQ: 88 case ENDP_STATUS: 89 case IPA_IRQ_STTS: 90 case IPA_IRQ_EN: 91 case IPA_IRQ_CLR: 92 case IPA_IRQ_UC: 93 case IRQ_SUSPEND_INFO: 94 return true; /* These should be defined for all versions */ 95 96 default: 97 return false; 98 } 99 } 100 101 const struct reg *ipa_reg(struct ipa *ipa, enum ipa_reg_id reg_id) 102 { 103 if (WARN(!ipa_reg_id_valid(ipa, reg_id), "invalid reg %u\n", reg_id)) 104 return NULL; 105 106 return reg(ipa->regs, reg_id); 107 } 108 109 static const struct regs *ipa_regs(enum ipa_version version) 110 { 111 switch (version) { 112 case IPA_VERSION_3_1: 113 return &ipa_regs_v3_1; 114 case IPA_VERSION_3_5_1: 115 return &ipa_regs_v3_5_1; 116 case IPA_VERSION_4_2: 117 return &ipa_regs_v4_2; 118 case IPA_VERSION_4_5: 119 return &ipa_regs_v4_5; 120 case IPA_VERSION_4_7: 121 return &ipa_regs_v4_7; 122 case IPA_VERSION_4_9: 123 return &ipa_regs_v4_9; 124 case IPA_VERSION_4_11: 125 return &ipa_regs_v4_11; 126 case IPA_VERSION_5_0: 127 return &ipa_regs_v5_0; 128 default: 129 return NULL; 130 } 131 } 132 133 int ipa_reg_init(struct ipa *ipa) 134 { 135 struct device *dev = &ipa->pdev->dev; 136 const struct regs *regs; 137 struct resource *res; 138 139 regs = ipa_regs(ipa->version); 140 if (!regs) 141 return -EINVAL; 142 143 if (WARN_ON(regs->reg_count > IPA_REG_ID_COUNT)) 144 return -EINVAL; 145 146 /* Setup IPA register memory */ 147 res = platform_get_resource_byname(ipa->pdev, IORESOURCE_MEM, 148 "ipa-reg"); 149 if (!res) { 150 dev_err(dev, "DT error getting \"ipa-reg\" memory property\n"); 151 return -ENODEV; 152 } 153 154 ipa->reg_virt = ioremap(res->start, resource_size(res)); 155 if (!ipa->reg_virt) { 156 dev_err(dev, "unable to remap \"ipa-reg\" memory\n"); 157 return -ENOMEM; 158 } 159 ipa->regs = regs; 160 161 return 0; 162 } 163 164 void ipa_reg_exit(struct ipa *ipa) 165 { 166 iounmap(ipa->reg_virt); 167 } 168