Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (C) 2013 Freescale Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #define pr_fmt(fmt)    "fsl-pamu: %s: " fmt, __func__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include "fsl_pamu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/fsl/guts.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/genalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <asm/mpc85xx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) /* define indexes for each operation mapping scenario */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #define OMI_QMAN        0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #define OMI_FMAN        0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #define OMI_QMAN_PRIV   0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #define OMI_CAAM        0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #define make64(high, low) (((u64)(high) << 32) | (low))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) struct pamu_isr_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 	void __iomem *pamu_reg_base;	/* Base address of PAMU regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 	unsigned int count;		/* The number of PAMUs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) static struct paace *ppaact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) static struct paace *spaact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) static bool probed;			/* Has PAMU been probed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  * Table for matching compatible strings, for device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  * guts node, for QorIQ SOCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  * string would be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) static const struct of_device_id guts_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	{ .compatible = "fsl,qoriq-device-config-1.0", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	{ .compatible = "fsl,qoriq-device-config-2.0", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  * Table for matching compatible strings, for device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50)  * L3 cache controller node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51)  * "fsl,t4240-l3-cache-controller" corresponds to T4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52)  * "fsl,b4860-l3-cache-controller" corresponds to B4 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53)  * "fsl,p4080-l3-cache-controller" corresponds to other,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54)  * SOCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) static const struct of_device_id l3_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	{ .compatible = "fsl,t4240-l3-cache-controller", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	{ .compatible = "fsl,b4860-l3-cache-controller", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	{ .compatible = "fsl,p4080-l3-cache-controller", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) /* maximum subwindows permitted per liodn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) static u32 max_subwindow_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) /* Pool for fspi allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) static struct gen_pool *spaace_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  * pamu_get_max_subwin_cnt() - Return the maximum supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71)  * subwindow count per liodn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) u32 pamu_get_max_subwin_cnt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	return max_subwindow_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  * pamu_get_ppaace() - Return the primary PACCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  * @liodn: liodn PAACT index for desired PAACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  * Returns the ppace pointer upon success else return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * null.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) static struct paace *pamu_get_ppaace(int liodn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	if (!ppaact || liodn >= PAACE_NUMBER_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 		pr_debug("PPAACT doesn't exist\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	return &ppaact[liodn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)  * pamu_enable_liodn() - Set valid bit of PACCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  * @liodn: liodn PAACT index for desired PAACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * Returns 0 upon success else error code < 0 returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) int pamu_enable_liodn(int liodn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	struct paace *ppaace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	ppaace = pamu_get_ppaace(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	if (!ppaace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		pr_debug("Invalid primary paace entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	if (!get_bf(ppaace->addr_bitfields, PPAACE_AF_WSE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		pr_debug("liodn %d not configured\n", liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	/* Ensure that all other stores to the ppaace complete first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	set_bf(ppaace->addr_bitfields, PAACE_AF_V, PAACE_V_VALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  * pamu_disable_liodn() - Clears valid bit of PACCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  * @liodn: liodn PAACT index for desired PAACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  * Returns 0 upon success else error code < 0 returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) int pamu_disable_liodn(int liodn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	struct paace *ppaace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	ppaace = pamu_get_ppaace(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	if (!ppaace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		pr_debug("Invalid primary paace entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	set_bf(ppaace->addr_bitfields, PAACE_AF_V, PAACE_V_INVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) /* Derive the window size encoding for a particular PAACE entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) static unsigned int map_addrspace_size_to_wse(phys_addr_t addrspace_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	/* Bug if not a power of 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	BUG_ON(addrspace_size & (addrspace_size - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	/* window size is 2^(WSE+1) bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	return fls64(addrspace_size) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) /* Derive the PAACE window count encoding for the subwindow count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) static unsigned int map_subwindow_cnt_to_wce(u32 subwindow_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	/* window count is 2^(WCE+1) bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	return __ffs(subwindow_cnt) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  * Set the PAACE type as primary and set the coherency required domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) static void pamu_init_ppaace(struct paace *ppaace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	set_bf(ppaace->addr_bitfields, PAACE_AF_PT, PAACE_PT_PRIMARY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	set_bf(ppaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	       PAACE_M_COHERENCE_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178)  * Set the PAACE type as secondary and set the coherency required domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)  * attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) static void pamu_init_spaace(struct paace *spaace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	set_bf(spaace->addr_bitfields, PAACE_AF_PT, PAACE_PT_SECONDARY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	set_bf(spaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	       PAACE_M_COHERENCE_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  * Return the spaace (corresponding to the secondary window index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  * for a particular ppaace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) static struct paace *pamu_get_spaace(struct paace *paace, u32 wnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	u32 subwin_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	struct paace *spaace = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	subwin_cnt = 1UL << (get_bf(paace->impl_attr, PAACE_IA_WCE) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	if (wnum < subwin_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		spaace = &spaact[paace->fspi + wnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		pr_debug("secondary paace out of bounds\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	return spaace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208)  * pamu_get_fspi_and_allocate() - Allocates fspi index and reserves subwindows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209)  *                                required for primary PAACE in the secondary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210)  *                                PAACE table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211)  * @subwin_cnt: Number of subwindows to be reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213)  * A PPAACE entry may have a number of associated subwindows. A subwindow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214)  * corresponds to a SPAACE entry in the SPAACT table. Each PAACE entry stores
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215)  * the index (fspi) of the first SPAACE entry in the SPAACT table. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216)  * function returns the index of the first SPAACE entry. The remaining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217)  * SPAACE entries are reserved contiguously from that index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219)  * Returns a valid fspi index in the range of 0 - SPAACE_NUMBER_ENTRIES on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220)  * If no SPAACE entry is available or the allocator can not reserve the required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221)  * number of contiguous entries function returns ULONG_MAX indicating a failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) static unsigned long pamu_get_fspi_and_allocate(u32 subwin_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	unsigned long spaace_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	spaace_addr = gen_pool_alloc(spaace_pool, subwin_cnt * sizeof(struct paace));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	if (!spaace_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		return ULONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	return (spaace_addr - (unsigned long)spaact) / (sizeof(struct paace));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) /* Release the subwindows reserved for a particular LIODN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) void pamu_free_subwins(int liodn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	struct paace *ppaace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	u32 subwin_cnt, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	ppaace = pamu_get_ppaace(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	if (!ppaace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		pr_debug("Invalid liodn entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	if (get_bf(ppaace->addr_bitfields, PPAACE_AF_MW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		subwin_cnt = 1UL << (get_bf(ppaace->impl_attr, PAACE_IA_WCE) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		size = (subwin_cnt - 1) * sizeof(struct paace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		gen_pool_free(spaace_pool, (unsigned long)&spaact[ppaace->fspi], size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256)  * Function used for updating stash destination for the coressponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257)  * LIODN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) int  pamu_update_paace_stash(int liodn, u32 subwin, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	struct paace *paace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	paace = pamu_get_ppaace(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	if (!paace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		pr_debug("Invalid liodn entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	if (subwin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		paace = pamu_get_spaace(paace, subwin - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		if (!paace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	set_bf(paace->impl_attr, PAACE_IA_CID, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) /* Disable a subwindow corresponding to the LIODN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) int pamu_disable_spaace(int liodn, u32 subwin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	struct paace *paace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	paace = pamu_get_ppaace(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	if (!paace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		pr_debug("Invalid liodn entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	if (subwin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		paace = pamu_get_spaace(paace, subwin - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		if (!paace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		set_bf(paace->addr_bitfields, PAACE_AF_V, PAACE_V_INVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		set_bf(paace->addr_bitfields, PAACE_AF_AP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		       PAACE_AP_PERMS_DENIED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306)  * pamu_config_paace() - Sets up PPAACE entry for specified liodn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308)  * @liodn: Logical IO device number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309)  * @win_addr: starting address of DSA window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310)  * @win-size: size of DSA window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311)  * @omi: Operation mapping index -- if ~omi == 0 then omi not defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312)  * @rpn: real (true physical) page number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313)  * @stashid: cache stash id for associated cpu -- if ~stashid == 0 then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314)  *	     stashid not defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)  * @snoopid: snoop id for hardware coherency -- if ~snoopid == 0 then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)  *	     snoopid not defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  * @subwin_cnt: number of sub-windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)  * @prot: window permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)  * Returns 0 upon success else error code < 0 returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		       u32 omi, unsigned long rpn, u32 snoopid, u32 stashid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		       u32 subwin_cnt, int prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	struct paace *ppaace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	unsigned long fspi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	if ((win_size & (win_size - 1)) || win_size < PAMU_PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		pr_debug("window size too small or not a power of two %pa\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 			 &win_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	if (win_addr & (win_size - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		pr_debug("window address is not aligned with window size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	ppaace = pamu_get_ppaace(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	if (!ppaace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	/* window size is 2^(WSE+1) bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	set_bf(ppaace->addr_bitfields, PPAACE_AF_WSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	       map_addrspace_size_to_wse(win_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	pamu_init_ppaace(ppaace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	ppaace->wbah = win_addr >> (PAMU_PAGE_SHIFT + 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	set_bf(ppaace->addr_bitfields, PPAACE_AF_WBAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	       (win_addr >> PAMU_PAGE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	/* set up operation mapping if it's configured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	if (omi < OME_NUMBER_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		set_bf(ppaace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		ppaace->op_encode.index_ot.omi = omi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	} else if (~omi != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		pr_debug("bad operation mapping index: %d\n", omi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	/* configure stash id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	if (~stashid != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		set_bf(ppaace->impl_attr, PAACE_IA_CID, stashid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	/* configure snoop id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	if (~snoopid != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		ppaace->domain_attr.to_host.snpid = snoopid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	if (subwin_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		/* The first entry is in the primary PAACE instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		fspi = pamu_get_fspi_and_allocate(subwin_cnt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		if (fspi == ULONG_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 			pr_debug("spaace indexes exhausted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		/* window count is 2^(WCE+1) bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		set_bf(ppaace->impl_attr, PAACE_IA_WCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		       map_subwindow_cnt_to_wce(subwin_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		ppaace->fspi = fspi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		set_bf(ppaace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		ppaace->twbah = rpn >> 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		set_bf(ppaace->win_bitfields, PAACE_WIN_TWBAL, rpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		set_bf(ppaace->addr_bitfields, PAACE_AF_AP, prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		set_bf(ppaace->impl_attr, PAACE_IA_WCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398)  * pamu_config_spaace() - Sets up SPAACE entry for specified subwindow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400)  * @liodn:  Logical IO device number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401)  * @subwin_cnt:  number of sub-windows associated with dma-window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)  * @subwin: subwindow index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403)  * @subwin_size: size of subwindow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404)  * @omi: Operation mapping index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405)  * @rpn: real (true physical) page number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406)  * @snoopid: snoop id for hardware coherency -- if ~snoopid == 0 then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407)  *			  snoopid not defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408)  * @stashid: cache stash id for associated cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409)  * @enable: enable/disable subwindow after reconfiguration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410)  * @prot: sub window permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412)  * Returns 0 upon success else error code < 0 returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		       phys_addr_t subwin_size, u32 omi, unsigned long rpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		       u32 snoopid, u32 stashid, int enable, int prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	struct paace *paace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	/* setup sub-windows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	if (!subwin_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		pr_debug("Invalid subwindow count\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	paace = pamu_get_ppaace(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	if (subwin > 0 && subwin < subwin_cnt && paace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		paace = pamu_get_spaace(paace, subwin - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		if (paace && !(paace->addr_bitfields & PAACE_V_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 			pamu_init_spaace(paace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			set_bf(paace->addr_bitfields, SPAACE_AF_LIODN, liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	if (!paace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		pr_debug("Invalid liodn entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	if ((subwin_size & (subwin_size - 1)) || subwin_size < PAMU_PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		pr_debug("subwindow size out of range, or not a power of 2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	if (rpn == ULONG_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		pr_debug("real page number out of range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	/* window size is 2^(WSE+1) bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	set_bf(paace->win_bitfields, PAACE_WIN_SWSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	       map_addrspace_size_to_wse(subwin_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	set_bf(paace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	paace->twbah = rpn >> 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	set_bf(paace->win_bitfields, PAACE_WIN_TWBAL, rpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	set_bf(paace->addr_bitfields, PAACE_AF_AP, prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	/* configure snoop id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	if (~snoopid != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		paace->domain_attr.to_host.snpid = snoopid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	/* set up operation mapping if it's configured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	if (omi < OME_NUMBER_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		set_bf(paace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		paace->op_encode.index_ot.omi = omi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	} else if (~omi != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		pr_debug("bad operation mapping index: %d\n", omi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	if (~stashid != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		set_bf(paace->impl_attr, PAACE_IA_CID, stashid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		set_bf(paace->addr_bitfields, PAACE_AF_V, PAACE_V_VALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487)  * get_ome_index() - Returns the index in the operation mapping table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488)  *                   for device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489)  * @*omi_index: pointer for storing the index value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) void get_ome_index(u32 *omi_index, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	if (of_device_is_compatible(dev->of_node, "fsl,qman-portal"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		*omi_index = OMI_QMAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	if (of_device_is_compatible(dev->of_node, "fsl,qman"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		*omi_index = OMI_QMAN_PRIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501)  * get_stash_id - Returns stash destination id corresponding to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502)  *                cache type and vcpu.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  * @stash_dest_hint: L1, L2 or L3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504)  * @vcpu: vpcu target for a particular cache type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506)  * Returs stash on success or ~(u32)0 on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) u32 get_stash_id(u32 stash_dest_hint, u32 vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	const u32 *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	u32 cache_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	int len, found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	/* Fastpath, exit early if L3/CPC cache is target for stashing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	if (stash_dest_hint == PAMU_ATTR_CACHE_L3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		node = of_find_matching_node(NULL, l3_device_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		if (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 			prop = of_get_property(node, "cache-stash-id", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 			if (!prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 				pr_debug("missing cache-stash-id at %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 					 node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 				of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 				return ~(u32)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 			of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 			return be32_to_cpup(prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		return ~(u32)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	for_each_of_cpu_node(node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		prop = of_get_property(node, "reg", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		for (i = 0; i < len / sizeof(u32); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			if (be32_to_cpup(&prop[i]) == vcpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 				found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 				goto found_cpu_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) found_cpu_node:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	/* find the hwnode that represents the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	for (cache_level = PAMU_ATTR_CACHE_L1; (cache_level < PAMU_ATTR_CACHE_L3) && found; cache_level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		if (stash_dest_hint == cache_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			prop = of_get_property(node, "cache-stash-id", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 			if (!prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 				pr_debug("missing cache-stash-id at %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 					 node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 				of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 				return ~(u32)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 			return be32_to_cpup(prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		prop = of_get_property(node, "next-level-cache", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		if (!prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 			pr_debug("can't find next-level-cache at %pOF\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 			of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			return ~(u32)0;  /* can't traverse any further */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		/* advance to next node in cache hierarchy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		node = of_find_node_by_phandle(*prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 			pr_debug("Invalid node for cache hierarchy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 			return ~(u32)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	pr_debug("stash dest not found for %d on vcpu %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		 stash_dest_hint, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	return ~(u32)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) /* Identify if the PAACT table entry belongs to QMAN, BMAN or QMAN Portal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) #define QMAN_PAACE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) #define QMAN_PORTAL_PAACE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) #define BMAN_PAACE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586)  * Setup operation mapping and stash destinations for QMAN and QMAN portal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587)  * Memory accesses to QMAN and BMAN private memory need not be coherent, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588)  * clear the PAACE entry coherency attribute for them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) static void setup_qbman_paace(struct paace *ppaace, int  paace_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	switch (paace_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	case QMAN_PAACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		set_bf(ppaace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		ppaace->op_encode.index_ot.omi = OMI_QMAN_PRIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		/* setup QMAN Private data stashing for the L3 cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		set_bf(ppaace->impl_attr, PAACE_IA_CID, get_stash_id(PAMU_ATTR_CACHE_L3, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		set_bf(ppaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		       0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	case QMAN_PORTAL_PAACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		set_bf(ppaace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		ppaace->op_encode.index_ot.omi = OMI_QMAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		/* Set DQRR and Frame stashing for the L3 cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		set_bf(ppaace->impl_attr, PAACE_IA_CID, get_stash_id(PAMU_ATTR_CACHE_L3, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	case BMAN_PAACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		set_bf(ppaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		       0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615)  * Setup the operation mapping table for various devices. This is a static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616)  * table where each table index corresponds to a particular device. PAMU uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617)  * this table to translate device transaction to appropriate corenet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618)  * transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) static void setup_omt(struct ome *omt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	struct ome *ome;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	/* Configure OMI_QMAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	ome = &omt[OMI_QMAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	ome->moe[IOE_EREAD0_IDX] = EOE_VALID | EOE_RSA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	ome->moe[IOE_EWRITE0_IDX] = EOE_VALID | EOE_WWSAO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	ome->moe[IOE_DIRECT0_IDX] = EOE_VALID | EOE_LDEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	ome->moe[IOE_DIRECT1_IDX] = EOE_VALID | EOE_LDECPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	/* Configure OMI_FMAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	ome = &omt[OMI_FMAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	ome->moe[IOE_READ_IDX]  = EOE_VALID | EOE_READI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	/* Configure OMI_QMAN private */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	ome = &omt[OMI_QMAN_PRIV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	ome->moe[IOE_READ_IDX]  = EOE_VALID | EOE_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	ome->moe[IOE_EREAD0_IDX] = EOE_VALID | EOE_RSA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	ome->moe[IOE_EWRITE0_IDX] = EOE_VALID | EOE_WWSA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	/* Configure OMI_CAAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	ome = &omt[OMI_CAAM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	ome->moe[IOE_READ_IDX]  = EOE_VALID | EOE_READI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654)  * Get the maximum number of PAACT table entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)  * and subwindows supported by PAMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) static void get_pamu_cap_values(unsigned long pamu_reg_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	u32 pc_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	pc_val = in_be32((u32 *)(pamu_reg_base + PAMU_PC3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	/* Maximum number of subwindows per liodn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	max_subwindow_count = 1 << (1 + PAMU_PC3_MWCE(pc_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) /* Setup PAMU registers pointing to PAACT, SPAACT and OMT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) static int setup_one_pamu(unsigned long pamu_reg_base, unsigned long pamu_reg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 			  phys_addr_t ppaact_phys, phys_addr_t spaact_phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			  phys_addr_t omt_phys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	u32 *pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	struct pamu_mmap_regs *pamu_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	pc = (u32 *) (pamu_reg_base + PAMU_PC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	pamu_regs = (struct pamu_mmap_regs *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		(pamu_reg_base + PAMU_MMAP_REGS_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	/* set up pointers to corenet control blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	out_be32(&pamu_regs->ppbah, upper_32_bits(ppaact_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	out_be32(&pamu_regs->ppbal, lower_32_bits(ppaact_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	ppaact_phys = ppaact_phys + PAACT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	out_be32(&pamu_regs->pplah, upper_32_bits(ppaact_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	out_be32(&pamu_regs->pplal, lower_32_bits(ppaact_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	out_be32(&pamu_regs->spbah, upper_32_bits(spaact_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	out_be32(&pamu_regs->spbal, lower_32_bits(spaact_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	spaact_phys = spaact_phys + SPAACT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	out_be32(&pamu_regs->splah, upper_32_bits(spaact_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	out_be32(&pamu_regs->splal, lower_32_bits(spaact_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	out_be32(&pamu_regs->obah, upper_32_bits(omt_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	out_be32(&pamu_regs->obal, lower_32_bits(omt_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	omt_phys = omt_phys + OMT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	out_be32(&pamu_regs->olah, upper_32_bits(omt_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	out_be32(&pamu_regs->olal, lower_32_bits(omt_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	 * set PAMU enable bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	 * allow ppaact & omt to be cached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	 * & enable PAMU access violation interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	out_be32((u32 *)(pamu_reg_base + PAMU_PICS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		 PAMU_ACCESS_VIOLATION_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	out_be32(pc, PAMU_PC_PE | PAMU_PC_OCE | PAMU_PC_SPCC | PAMU_PC_PPCC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) /* Enable all device LIODNS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) static void setup_liodns(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	struct paace *ppaace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	struct device_node *node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	const u32 *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	for_each_node_with_property(node, "fsl,liodn") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		prop = of_get_property(node, "fsl,liodn", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		for (i = 0; i < len / sizeof(u32); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			int liodn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			liodn = be32_to_cpup(&prop[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			if (liodn >= PAACE_NUMBER_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				pr_debug("Invalid LIODN value %d\n", liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			ppaace = pamu_get_ppaace(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			pamu_init_ppaace(ppaace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			/* window size is 2^(WSE+1) bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			set_bf(ppaace->addr_bitfields, PPAACE_AF_WSE, 35);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			ppaace->wbah = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			set_bf(ppaace->addr_bitfields, PPAACE_AF_WBAL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			set_bf(ppaace->impl_attr, PAACE_IA_ATM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			       PAACE_ATM_NO_XLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			set_bf(ppaace->addr_bitfields, PAACE_AF_AP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			       PAACE_AP_PERMS_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			if (of_device_is_compatible(node, "fsl,qman-portal"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 				setup_qbman_paace(ppaace, QMAN_PORTAL_PAACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			if (of_device_is_compatible(node, "fsl,qman"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 				setup_qbman_paace(ppaace, QMAN_PAACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			if (of_device_is_compatible(node, "fsl,bman"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 				setup_qbman_paace(ppaace, BMAN_PAACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			pamu_enable_liodn(liodn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) static irqreturn_t pamu_av_isr(int irq, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	struct pamu_isr_data *data = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	phys_addr_t phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	unsigned int i, j, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	pr_emerg("access violation interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	for (i = 0; i < data->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		void __iomem *p = data->pamu_reg_base + i * PAMU_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		u32 pics = in_be32(p + PAMU_PICS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		if (pics & PAMU_ACCESS_VIOLATION_STAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			u32 avs1 = in_be32(p + PAMU_AVS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			struct paace *paace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 			pr_emerg("POES1=%08x\n", in_be32(p + PAMU_POES1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 			pr_emerg("POES2=%08x\n", in_be32(p + PAMU_POES2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			pr_emerg("AVS1=%08x\n", avs1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 			pr_emerg("AVS2=%08x\n", in_be32(p + PAMU_AVS2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			pr_emerg("AVA=%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 				 make64(in_be32(p + PAMU_AVAH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 					in_be32(p + PAMU_AVAL)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			pr_emerg("UDAD=%08x\n", in_be32(p + PAMU_UDAD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			pr_emerg("POEA=%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 				 make64(in_be32(p + PAMU_POEAH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 					in_be32(p + PAMU_POEAL)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			phys = make64(in_be32(p + PAMU_POEAH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 				      in_be32(p + PAMU_POEAL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			/* Assume that POEA points to a PAACE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			if (phys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 				u32 *paace = phys_to_virt(phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 				/* Only the first four words are relevant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 				for (j = 0; j < 4; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 					pr_emerg("PAACE[%u]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 						 j, in_be32(paace + j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			/* clear access violation condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 			out_be32(p + PAMU_AVS1, avs1 & PAMU_AV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			paace = pamu_get_ppaace(avs1 >> PAMU_AVS1_LIODN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			BUG_ON(!paace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			/* check if we got a violation for a disabled LIODN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			if (!get_bf(paace->addr_bitfields, PAACE_AF_V)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 				 * As per hardware erratum A-003638, access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 				 * violation can be reported for a disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 				 * LIODN. If we hit that condition, disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 				 * access violation reporting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 				pics &= ~PAMU_ACCESS_VIOLATION_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 				/* Disable the LIODN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 				ret = pamu_disable_liodn(avs1 >> PAMU_AVS1_LIODN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 				BUG_ON(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 				pr_emerg("Disabling liodn %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 					 avs1 >> PAMU_AVS1_LIODN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 			out_be32((p + PAMU_PICS), pics);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) #define LAWAR_EN		0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) #define LAWAR_TARGET_MASK	0x0FF00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) #define LAWAR_TARGET_SHIFT	20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) #define LAWAR_SIZE_MASK		0x0000003F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) #define LAWAR_CSDID_MASK	0x000FF000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) #define LAWAR_CSDID_SHIFT	12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) #define LAW_SIZE_4K		0xb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) struct ccsr_law {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	u32	lawbarh;	/* LAWn base address high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	u32	lawbarl;	/* LAWn base address low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	u32	lawar;		/* LAWn attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	u32	reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835)  * Create a coherence subdomain for a given memory block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) static int create_csd(phys_addr_t phys, size_t size, u32 csd_port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	const __be32 *iprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	void __iomem *lac = NULL;	/* Local Access Control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	struct ccsr_law __iomem *law;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	void __iomem *ccm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	u32 __iomem *csdids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	unsigned int i, num_laws, num_csds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	u32 law_target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	u32 csd_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	np = of_find_compatible_node(NULL, NULL, "fsl,corenet-law");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	iprop = of_get_property(np, "fsl,num-laws", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	if (!iprop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	num_laws = be32_to_cpup(iprop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (!num_laws) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	lac = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	if (!lac) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	/* LAW registers are at offset 0xC00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	law = lac + 0xC00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	np = of_find_compatible_node(NULL, NULL, "fsl,corenet-cf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	iprop = of_get_property(np, "fsl,ccf-num-csdids", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	if (!iprop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	num_csds = be32_to_cpup(iprop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	if (!num_csds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	ccm = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	if (!ccm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	/* The undocumented CSDID registers are at offset 0x600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	csdids = ccm + 0x600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	/* Find an unused coherence subdomain ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	for (csd_id = 0; csd_id < num_csds; csd_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		if (!csdids[csd_id])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	/* Store the Port ID in the (undocumented) proper CIDMRxx register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	csdids[csd_id] = csd_port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	/* Find the DDR LAW that maps to our buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	for (i = 0; i < num_laws; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		if (law[i].lawar & LAWAR_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 			phys_addr_t law_start, law_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 			law_start = make64(law[i].lawbarh, law[i].lawbarl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 			law_end = law_start +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 				(2ULL << (law[i].lawar & LAWAR_SIZE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 			if (law_start <= phys && phys < law_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 				law_target = law[i].lawar & LAWAR_TARGET_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	if (i == 0 || i == num_laws) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		/* This should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	/* Find a free LAW entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	while (law[--i].lawar & LAWAR_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 			/* No higher priority LAW slots available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 			ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	law[i].lawbarh = upper_32_bits(phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	law[i].lawbarl = lower_32_bits(phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	law[i].lawar = LAWAR_EN | law_target | (csd_id << LAWAR_CSDID_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		(LAW_SIZE_4K + get_order(size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	if (ccm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		iounmap(ccm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	if (lac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		iounmap(lac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	if (np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968)  * Table of SVRs and the corresponding PORT_ID values. Port ID corresponds to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969)  * bit map of snoopers for a given range of memory mapped by a LAW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)  * All future CoreNet-enabled SOCs will have this erratum(A-004510) fixed, so this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972)  * table should never need to be updated.  SVRs are guaranteed to be unique, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973)  * there is no worry that a future SOC will inadvertently have one of these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974)  * values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	u32 svr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	u32 port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) } port_id_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	{(SVR_P2040 << 8) | 0x10, 0xFF000000},	/* P2040 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	{(SVR_P2040 << 8) | 0x11, 0xFF000000},	/* P2040 1.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	{(SVR_P2041 << 8) | 0x10, 0xFF000000},	/* P2041 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	{(SVR_P2041 << 8) | 0x11, 0xFF000000},	/* P2041 1.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	{(SVR_P3041 << 8) | 0x10, 0xFF000000},	/* P3041 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	{(SVR_P3041 << 8) | 0x11, 0xFF000000},	/* P3041 1.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	{(SVR_P4040 << 8) | 0x20, 0xFFF80000},	/* P4040 2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	{(SVR_P4080 << 8) | 0x20, 0xFFF80000},	/* P4080 2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	{(SVR_P5010 << 8) | 0x10, 0xFC000000},	/* P5010 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	{(SVR_P5010 << 8) | 0x20, 0xFC000000},	/* P5010 2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	{(SVR_P5020 << 8) | 0x10, 0xFC000000},	/* P5020 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	{(SVR_P5021 << 8) | 0x10, 0xFF800000},	/* P5021 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	{(SVR_P5040 << 8) | 0x10, 0xFF800000},	/* P5040 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) #define SVR_SECURITY	0x80000	/* The Security (E) bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) static int fsl_pamu_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	void __iomem *pamu_regs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	struct ccsr_guts __iomem *guts_regs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	u32 pamubypenr, pamu_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	unsigned long pamu_reg_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	unsigned long pamu_reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	struct pamu_isr_data *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	struct device_node *guts_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	u64 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	struct page *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	phys_addr_t ppaact_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	phys_addr_t spaact_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	struct ome *omt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	phys_addr_t omt_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	size_t mem_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	unsigned int order = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	u32 csd_port_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	 * enumerate all PAMUs and allocate and setup PAMU tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	 * for each of them,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	 * NOTE : All PAMUs share the same LIODN tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	if (WARN_ON(probed))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	pamu_regs = of_iomap(dev->of_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	if (!pamu_regs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		dev_err(dev, "ioremap of PAMU node failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	of_get_address(dev->of_node, 0, &size, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	irq = irq_of_parse_and_map(dev->of_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	if (irq == NO_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		dev_warn(dev, "no interrupts listed in PAMU node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	data->pamu_reg_base = pamu_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	data->count = size / PAMU_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	/* The ISR needs access to the regs, so we won't iounmap them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	ret = request_irq(irq, pamu_av_isr, 0, "pamu", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		dev_err(dev, "error %i installing ISR for irq %i\n", ret, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	guts_node = of_find_matching_node(NULL, guts_device_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	if (!guts_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		dev_err(dev, "could not find GUTS node %pOF\n", dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	guts_regs = of_iomap(guts_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	of_node_put(guts_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	if (!guts_regs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		dev_err(dev, "ioremap of GUTS node failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	/* read in the PAMU capability registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	get_pamu_cap_values((unsigned long)pamu_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	 * To simplify the allocation of a coherency domain, we allocate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	 * PAACT and the OMT in the same memory buffer.  Unfortunately, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	 * wastes more memory compared to allocating the buffers separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	/* Determine how much memory we need */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	mem_size = (PAGE_SIZE << get_order(PAACT_SIZE)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		(PAGE_SIZE << get_order(SPAACT_SIZE)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		(PAGE_SIZE << get_order(OMT_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	order = get_order(mem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	p = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		dev_err(dev, "unable to allocate PAACT/SPAACT/OMT block\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	ppaact = page_address(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	ppaact_phys = page_to_phys(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	/* Make sure the memory is naturally aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	if (ppaact_phys & ((PAGE_SIZE << order) - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		dev_err(dev, "PAACT/OMT block is unaligned\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	spaact = (void *)ppaact + (PAGE_SIZE << get_order(PAACT_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	omt = (void *)spaact + (PAGE_SIZE << get_order(SPAACT_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	dev_dbg(dev, "ppaact virt=%p phys=%pa\n", ppaact, &ppaact_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	/* Check to see if we need to implement the work-around on this SOC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	/* Determine the Port ID for our coherence subdomain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	for (i = 0; i < ARRAY_SIZE(port_id_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		if (port_id_map[i].svr == (mfspr(SPRN_SVR) & ~SVR_SECURITY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 			csd_port_id = port_id_map[i].port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 			dev_dbg(dev, "found matching SVR %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 				port_id_map[i].svr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	if (csd_port_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		dev_dbg(dev, "creating coherency subdomain at address %pa, size %zu, port id 0x%08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			&ppaact_phys, mem_size, csd_port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		ret = create_csd(ppaact_phys, mem_size, csd_port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			dev_err(dev, "could not create coherence subdomain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	spaact_phys = virt_to_phys(spaact);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	omt_phys = virt_to_phys(omt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	spaace_pool = gen_pool_create(ilog2(sizeof(struct paace)), -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	if (!spaace_pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		dev_err(dev, "Failed to allocate spaace gen pool\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	ret = gen_pool_add(spaace_pool, (unsigned long)spaact, SPAACT_SIZE, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		goto error_genpool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	pamubypenr = in_be32(&guts_regs->pamubypenr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	for (pamu_reg_off = 0, pamu_counter = 0x80000000; pamu_reg_off < size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	     pamu_reg_off += PAMU_OFFSET, pamu_counter >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		pamu_reg_base = (unsigned long)pamu_regs + pamu_reg_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		setup_one_pamu(pamu_reg_base, pamu_reg_off, ppaact_phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 			       spaact_phys, omt_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		/* Disable PAMU bypass for this PAMU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		pamubypenr &= ~pamu_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	setup_omt(omt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	/* Enable all relevant PAMU(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	out_be32(&guts_regs->pamubypenr, pamubypenr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	iounmap(guts_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	/* Enable DMA for the LIODNs in the device tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	setup_liodns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	probed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) error_genpool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	gen_pool_destroy(spaace_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	if (irq != NO_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		free_irq(irq, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	kfree_sensitive(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	if (pamu_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		iounmap(pamu_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	if (guts_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		iounmap(guts_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	if (ppaact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		free_pages((unsigned long)ppaact, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	ppaact = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static struct platform_driver fsl_of_pamu_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		.name = "fsl-of-pamu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	.probe = fsl_pamu_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) static __init int fsl_pamu_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	struct platform_device *pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	 * The normal OF process calls the probe function at some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	 * indeterminate later time, after most drivers have loaded.  This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	 * too late for us, because PAMU clients (like the Qman driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	 * depend on PAMU being initialized early.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	 * So instead, we "manually" call our probe function by creating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	 * platform devices ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	 * We assume that there is only one PAMU node in the device tree.  A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	 * single PAMU node represents all of the PAMU devices in the SOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	 * already.   Everything else already makes that assumption, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	 * binding for the PAMU nodes doesn't allow for any parent-child
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	 * relationships anyway.  In other words, support for more than one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	 * PAMU node would require significant changes to a lot of code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	np = of_find_compatible_node(NULL, NULL, "fsl,pamu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		pr_err("could not find a PAMU node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	ret = platform_driver_register(&fsl_of_pamu_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		pr_err("could not register driver (err=%i)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 		goto error_driver_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	pdev = platform_device_alloc("fsl-of-pamu", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		pr_err("could not allocate device %pOF\n", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		goto error_device_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	pdev->dev.of_node = of_node_get(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	ret = pamu_domain_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		goto error_device_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	ret = platform_device_add(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		pr_err("could not add device %pOF (err=%i)\n", np, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		goto error_device_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) error_device_add:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	of_node_put(pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	pdev->dev.of_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) error_device_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	platform_driver_unregister(&fsl_of_pamu_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) error_driver_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) arch_initcall(fsl_pamu_init);