xref: /openbmc/linux/drivers/net/ipa/ipa_reg.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1cdf2e941SAlex Elder // SPDX-License-Identifier: GPL-2.0
2cdf2e941SAlex Elder 
3cdf2e941SAlex Elder /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
421e8aacaSAlex Elder  * Copyright (C) 2019-2023 Linaro Ltd.
5cdf2e941SAlex Elder  */
6cdf2e941SAlex Elder 
7cdf2e941SAlex Elder #include <linux/io.h>
8cdf2e941SAlex Elder 
9cdf2e941SAlex Elder #include "ipa.h"
10cdf2e941SAlex Elder #include "ipa_reg.h"
11cdf2e941SAlex Elder 
12d86603e9SAlex Elder /* Is this register ID valid for the current IPA version? */
ipa_reg_id_valid(struct ipa * ipa,enum ipa_reg_id reg_id)13d86603e9SAlex Elder static bool ipa_reg_id_valid(struct ipa *ipa, enum ipa_reg_id reg_id)
1498e2dd71SAlex Elder {
1598e2dd71SAlex Elder 	enum ipa_version version = ipa->version;
1698e2dd71SAlex Elder 
1798e2dd71SAlex Elder 	switch (reg_id) {
1821e8aacaSAlex Elder 	case FILT_ROUT_HASH_EN:
1921e8aacaSAlex Elder 		return version == IPA_VERSION_4_2;
2021e8aacaSAlex Elder 
2121e8aacaSAlex Elder 	case FILT_ROUT_HASH_FLUSH:
2221e8aacaSAlex Elder 		return version < IPA_VERSION_5_0 && version != IPA_VERSION_4_2;
2321e8aacaSAlex Elder 
2421e8aacaSAlex Elder 	case FILT_ROUT_CACHE_FLUSH:
2521e8aacaSAlex Elder 	case ENDP_FILTER_CACHE_CFG:
2621e8aacaSAlex Elder 	case ENDP_ROUTER_CACHE_CFG:
2721e8aacaSAlex Elder 		return version >= IPA_VERSION_5_0;
2821e8aacaSAlex Elder 
2998e2dd71SAlex Elder 	case IPA_BCR:
3098e2dd71SAlex Elder 	case COUNTER_CFG:
3181772e44SAlex Elder 		return version < IPA_VERSION_4_5;
3298e2dd71SAlex Elder 
3398e2dd71SAlex Elder 	case IPA_TX_CFG:
3498e2dd71SAlex Elder 	case FLAVOR_0:
3598e2dd71SAlex Elder 	case IDLE_INDICATION_CFG:
3681772e44SAlex Elder 		return version >= IPA_VERSION_3_5;
3798e2dd71SAlex Elder 
3898e2dd71SAlex Elder 	case QTIME_TIMESTAMP_CFG:
3998e2dd71SAlex Elder 	case TIMERS_XO_CLK_DIV_CFG:
4098e2dd71SAlex Elder 	case TIMERS_PULSE_GRAN_CFG:
4181772e44SAlex Elder 		return version >= IPA_VERSION_4_5;
4298e2dd71SAlex Elder 
4398e2dd71SAlex Elder 	case SRC_RSRC_GRP_45_RSRC_TYPE:
4498e2dd71SAlex Elder 	case DST_RSRC_GRP_45_RSRC_TYPE:
4581772e44SAlex Elder 		return version <= IPA_VERSION_3_1 ||
4621e8aacaSAlex Elder 		       version == IPA_VERSION_4_5 ||
4721e8aacaSAlex Elder 		       version == IPA_VERSION_5_0;
4898e2dd71SAlex Elder 
4998e2dd71SAlex Elder 	case SRC_RSRC_GRP_67_RSRC_TYPE:
5098e2dd71SAlex Elder 	case DST_RSRC_GRP_67_RSRC_TYPE:
5121e8aacaSAlex Elder 		return version <= IPA_VERSION_3_1 ||
5221e8aacaSAlex Elder 		       version == IPA_VERSION_5_0;
5398e2dd71SAlex Elder 
5498e2dd71SAlex Elder 	case ENDP_FILTER_ROUTER_HSH_CFG:
55786bbe50SAlex Elder 		return version < IPA_VERSION_5_0 &&
56786bbe50SAlex Elder 			version != IPA_VERSION_4_2;
5798e2dd71SAlex Elder 
5898e2dd71SAlex Elder 	case IRQ_SUSPEND_EN:
5998e2dd71SAlex Elder 	case IRQ_SUSPEND_CLR:
6081772e44SAlex Elder 		return version >= IPA_VERSION_3_1;
6198e2dd71SAlex Elder 
62d86603e9SAlex Elder 	case COMP_CFG:
63d86603e9SAlex Elder 	case CLKON_CFG:
64d86603e9SAlex Elder 	case ROUTE:
65d86603e9SAlex Elder 	case SHARED_MEM_SIZE:
66d86603e9SAlex Elder 	case QSB_MAX_WRITES:
67d86603e9SAlex Elder 	case QSB_MAX_READS:
68d86603e9SAlex Elder 	case STATE_AGGR_ACTIVE:
69d86603e9SAlex Elder 	case LOCAL_PKT_PROC_CNTXT:
70d86603e9SAlex Elder 	case AGGR_FORCE_CLOSE:
71d86603e9SAlex Elder 	case SRC_RSRC_GRP_01_RSRC_TYPE:
72d86603e9SAlex Elder 	case SRC_RSRC_GRP_23_RSRC_TYPE:
73d86603e9SAlex Elder 	case DST_RSRC_GRP_01_RSRC_TYPE:
74d86603e9SAlex Elder 	case DST_RSRC_GRP_23_RSRC_TYPE:
75d86603e9SAlex Elder 	case ENDP_INIT_CTRL:
76d86603e9SAlex Elder 	case ENDP_INIT_CFG:
77d86603e9SAlex Elder 	case ENDP_INIT_NAT:
78d86603e9SAlex Elder 	case ENDP_INIT_HDR:
79d86603e9SAlex Elder 	case ENDP_INIT_HDR_EXT:
80d86603e9SAlex Elder 	case ENDP_INIT_HDR_METADATA_MASK:
81d86603e9SAlex Elder 	case ENDP_INIT_MODE:
82d86603e9SAlex Elder 	case ENDP_INIT_AGGR:
83d86603e9SAlex Elder 	case ENDP_INIT_HOL_BLOCK_EN:
84d86603e9SAlex Elder 	case ENDP_INIT_HOL_BLOCK_TIMER:
85d86603e9SAlex Elder 	case ENDP_INIT_DEAGGR:
86d86603e9SAlex Elder 	case ENDP_INIT_RSRC_GRP:
87d86603e9SAlex Elder 	case ENDP_INIT_SEQ:
88d86603e9SAlex Elder 	case ENDP_STATUS:
89d86603e9SAlex Elder 	case IPA_IRQ_STTS:
90d86603e9SAlex Elder 	case IPA_IRQ_EN:
91d86603e9SAlex Elder 	case IPA_IRQ_CLR:
92d86603e9SAlex Elder 	case IPA_IRQ_UC:
93d86603e9SAlex Elder 	case IRQ_SUSPEND_INFO:
9481772e44SAlex Elder 		return true;	/* These should be defined for all versions */
95d86603e9SAlex Elder 
9698e2dd71SAlex Elder 	default:
9781772e44SAlex Elder 		return false;
9881772e44SAlex Elder 	}
9998e2dd71SAlex Elder }
10098e2dd71SAlex Elder 
ipa_reg(struct ipa * ipa,enum ipa_reg_id reg_id)10181772e44SAlex Elder const struct reg *ipa_reg(struct ipa *ipa, enum ipa_reg_id reg_id)
1026bfb7538SAlex Elder {
10381772e44SAlex Elder 	if (WARN(!ipa_reg_id_valid(ipa, reg_id), "invalid reg %u\n", reg_id))
1046a244b75SAlex Elder 		return NULL;
1056bfb7538SAlex Elder 
10681772e44SAlex Elder 	return reg(ipa->regs, reg_id);
1076bfb7538SAlex Elder }
1086bfb7538SAlex Elder 
ipa_regs(enum ipa_version version)10981772e44SAlex Elder static const struct regs *ipa_regs(enum ipa_version version)
11007f120bcSAlex Elder {
11107f120bcSAlex Elder 	switch (version) {
11207f120bcSAlex Elder 	case IPA_VERSION_3_1:
11307f120bcSAlex Elder 		return &ipa_regs_v3_1;
11407f120bcSAlex Elder 	case IPA_VERSION_3_5_1:
11507f120bcSAlex Elder 		return &ipa_regs_v3_5_1;
11607f120bcSAlex Elder 	case IPA_VERSION_4_2:
11707f120bcSAlex Elder 		return &ipa_regs_v4_2;
11807f120bcSAlex Elder 	case IPA_VERSION_4_5:
11907f120bcSAlex Elder 		return &ipa_regs_v4_5;
120b310de78SAlex Elder 	case IPA_VERSION_4_7:
121b310de78SAlex Elder 		return &ipa_regs_v4_7;
12207f120bcSAlex Elder 	case IPA_VERSION_4_9:
12307f120bcSAlex Elder 		return &ipa_regs_v4_9;
12407f120bcSAlex Elder 	case IPA_VERSION_4_11:
12507f120bcSAlex Elder 		return &ipa_regs_v4_11;
126*ed4c7d61SAlex Elder 	case IPA_VERSION_5_0:
127*ed4c7d61SAlex Elder 		return &ipa_regs_v5_0;
12807f120bcSAlex Elder 	default:
12907f120bcSAlex Elder 		return NULL;
13007f120bcSAlex Elder 	}
13107f120bcSAlex Elder }
13207f120bcSAlex Elder 
ipa_reg_init(struct ipa * ipa)133cdf2e941SAlex Elder int ipa_reg_init(struct ipa *ipa)
134cdf2e941SAlex Elder {
135cdf2e941SAlex Elder 	struct device *dev = &ipa->pdev->dev;
13681772e44SAlex Elder 	const struct regs *regs;
137cdf2e941SAlex Elder 	struct resource *res;
138cdf2e941SAlex Elder 
13907f120bcSAlex Elder 	regs = ipa_regs(ipa->version);
14007f120bcSAlex Elder 	if (!regs)
14107f120bcSAlex Elder 		return -EINVAL;
14207f120bcSAlex Elder 
14307f120bcSAlex Elder 	if (WARN_ON(regs->reg_count > IPA_REG_ID_COUNT))
14407f120bcSAlex Elder 		return -EINVAL;
14507f120bcSAlex Elder 
146cdf2e941SAlex Elder 	/* Setup IPA register memory  */
147cdf2e941SAlex Elder 	res = platform_get_resource_byname(ipa->pdev, IORESOURCE_MEM,
148cdf2e941SAlex Elder 					   "ipa-reg");
149cdf2e941SAlex Elder 	if (!res) {
150cdf2e941SAlex Elder 		dev_err(dev, "DT error getting \"ipa-reg\" memory property\n");
151cdf2e941SAlex Elder 		return -ENODEV;
152cdf2e941SAlex Elder 	}
153cdf2e941SAlex Elder 
154cdf2e941SAlex Elder 	ipa->reg_virt = ioremap(res->start, resource_size(res));
155cdf2e941SAlex Elder 	if (!ipa->reg_virt) {
156cdf2e941SAlex Elder 		dev_err(dev, "unable to remap \"ipa-reg\" memory\n");
157cdf2e941SAlex Elder 		return -ENOMEM;
158cdf2e941SAlex Elder 	}
15907f120bcSAlex Elder 	ipa->regs = regs;
160cdf2e941SAlex Elder 
161cdf2e941SAlex Elder 	return 0;
162cdf2e941SAlex Elder }
163cdf2e941SAlex Elder 
ipa_reg_exit(struct ipa * ipa)164cdf2e941SAlex Elder void ipa_reg_exit(struct ipa *ipa)
165cdf2e941SAlex Elder {
166cdf2e941SAlex Elder 	iounmap(ipa->reg_virt);
167cdf2e941SAlex Elder }
168