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