170 lines · 3.8 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2019-2024 Linaro Ltd. */ #include <linux/io.h>#include <linux/platform_device.h> #include "ipa.h"#include "ipa_reg.h" /* Is this register ID valid for the current IPA version? */static bool ipa_reg_id_valid(struct ipa *ipa, enum ipa_reg_id reg_id){	enum ipa_version version = ipa->version; 	switch (reg_id) {	case FILT_ROUT_HASH_EN:		return version == IPA_VERSION_4_2; 	case FILT_ROUT_HASH_FLUSH:		return version < IPA_VERSION_5_0 && version != IPA_VERSION_4_2; 	case FILT_ROUT_CACHE_FLUSH:	case ENDP_FILTER_CACHE_CFG:	case ENDP_ROUTER_CACHE_CFG:		return version >= IPA_VERSION_5_0; 	case IPA_BCR:	case COUNTER_CFG:		return version < IPA_VERSION_4_5; 	case IPA_TX_CFG:	case FLAVOR_0:	case IDLE_INDICATION_CFG:		return version >= IPA_VERSION_3_5; 	case QTIME_TIMESTAMP_CFG:	case TIMERS_XO_CLK_DIV_CFG:	case TIMERS_PULSE_GRAN_CFG:		return version >= IPA_VERSION_4_5; 	case SRC_RSRC_GRP_45_RSRC_TYPE:	case DST_RSRC_GRP_45_RSRC_TYPE:		return version <= IPA_VERSION_3_1 ||		       version == IPA_VERSION_4_5 ||		       version >= IPA_VERSION_5_0; 	case SRC_RSRC_GRP_67_RSRC_TYPE:	case DST_RSRC_GRP_67_RSRC_TYPE:		return version <= IPA_VERSION_3_1 ||		       version >= IPA_VERSION_5_0; 	case ENDP_FILTER_ROUTER_HSH_CFG:		return version < IPA_VERSION_5_0 &&			version != IPA_VERSION_4_2; 	case IRQ_SUSPEND_EN:	case IRQ_SUSPEND_CLR:		return version >= IPA_VERSION_3_1; 	case COMP_CFG:	case CLKON_CFG:	case ROUTE:	case SHARED_MEM_SIZE:	case QSB_MAX_WRITES:	case QSB_MAX_READS:	case STATE_AGGR_ACTIVE:	case LOCAL_PKT_PROC_CNTXT:	case AGGR_FORCE_CLOSE:	case SRC_RSRC_GRP_01_RSRC_TYPE:	case SRC_RSRC_GRP_23_RSRC_TYPE:	case DST_RSRC_GRP_01_RSRC_TYPE:	case DST_RSRC_GRP_23_RSRC_TYPE:	case ENDP_INIT_CTRL:	case ENDP_INIT_CFG:	case ENDP_INIT_NAT:	case ENDP_INIT_HDR:	case ENDP_INIT_HDR_EXT:	case ENDP_INIT_HDR_METADATA_MASK:	case ENDP_INIT_MODE:	case ENDP_INIT_AGGR:	case ENDP_INIT_HOL_BLOCK_EN:	case ENDP_INIT_HOL_BLOCK_TIMER:	case ENDP_INIT_DEAGGR:	case ENDP_INIT_RSRC_GRP:	case ENDP_INIT_SEQ:	case ENDP_STATUS:	case IPA_IRQ_STTS:	case IPA_IRQ_EN:	case IPA_IRQ_CLR:	case IPA_IRQ_UC:	case IRQ_SUSPEND_INFO:		return true;	/* These should be defined for all versions */ 	default:		return false;	}} const struct reg *ipa_reg(struct ipa *ipa, enum ipa_reg_id reg_id){	if (WARN(!ipa_reg_id_valid(ipa, reg_id), "invalid reg %u\n", reg_id))		return NULL; 	return reg(ipa->regs, reg_id);} static const struct regs *ipa_regs(enum ipa_version version){	switch (version) {	case IPA_VERSION_3_1:		return &ipa_regs_v3_1;	case IPA_VERSION_3_5_1:		return &ipa_regs_v3_5_1;	case IPA_VERSION_4_2:		return &ipa_regs_v4_2;	case IPA_VERSION_4_5:		return &ipa_regs_v4_5;	case IPA_VERSION_4_7:		return &ipa_regs_v4_7;	case IPA_VERSION_4_9:		return &ipa_regs_v4_9;	case IPA_VERSION_4_11:		return &ipa_regs_v4_11;	case IPA_VERSION_5_0:	case IPA_VERSION_5_2:		return &ipa_regs_v5_0;	case IPA_VERSION_5_5:		return &ipa_regs_v5_5;	default:		return NULL;	}} int ipa_reg_init(struct ipa *ipa, struct platform_device *pdev){	struct device *dev = &pdev->dev;	const struct regs *regs;	struct resource *res; 	regs = ipa_regs(ipa->version);	if (!regs)		return -EINVAL; 	if (WARN_ON(regs->reg_count > IPA_REG_ID_COUNT))		return -EINVAL; 	/* Setup IPA register memory  */	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipa-reg");	if (!res) {		dev_err(dev, "DT error getting \"ipa-reg\" memory property\n");		return -ENODEV;	} 	ipa->reg_virt = ioremap(res->start, resource_size(res));	if (!ipa->reg_virt) {		dev_err(dev, "unable to remap \"ipa-reg\" memory\n");		return -ENOMEM;	}	ipa->regs = regs; 	return 0;} void ipa_reg_exit(struct ipa *ipa){	iounmap(ipa->reg_virt);}