From bedbef8ad3e75a304af6361af235302bcc61d06b Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 14 May 2024 06:39:01 +0000 Subject: [PATCH] 修改内核路径 --- kernel/drivers/soc/fsl/qbman/qman_ccsr.c | 74 ++++++++++++++++++++++++++++++++---- 1 files changed, 65 insertions(+), 9 deletions(-) diff --git a/kernel/drivers/soc/fsl/qbman/qman_ccsr.c b/kernel/drivers/soc/fsl/qbman/qman_ccsr.c index 6fd5fef..157659f 100644 --- a/kernel/drivers/soc/fsl/qbman/qman_ccsr.c +++ b/kernel/drivers/soc/fsl/qbman/qman_ccsr.c @@ -274,6 +274,7 @@ /* A SDQCR mask comprising all the available/visible pool channels */ static u32 qm_pools_sdqcr; static int __qman_probed; +static int __qman_requires_cleanup; static inline u32 qm_ccsr_in(u32 offset) { @@ -340,19 +341,55 @@ } #define PFDR_AR_EN BIT(31) -static void qm_set_memory(enum qm_memory memory, u64 ba, u32 size) +static int qm_set_memory(enum qm_memory memory, u64 ba, u32 size) { + void *ptr; u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE; u32 exp = ilog2(size); + u32 bar, bare; /* choke if size isn't within range */ DPAA_ASSERT((size >= 4096) && (size <= 1024*1024*1024) && is_power_of_2(size)); /* choke if 'ba' has lower-alignment than 'size' */ DPAA_ASSERT(!(ba & (size - 1))); + + /* Check to see if QMan has already been initialized */ + bar = qm_ccsr_in(offset + REG_offset_BAR); + if (bar) { + /* Maker sure ba == what was programmed) */ + bare = qm_ccsr_in(offset); + if (bare != upper_32_bits(ba) || bar != lower_32_bits(ba)) { + pr_err("Attempted to reinitialize QMan with different BAR, got 0x%llx read BARE=0x%x BAR=0x%x\n", + ba, bare, bar); + return -ENOMEM; + } + __qman_requires_cleanup = 1; + /* Return 1 to indicate memory was previously programmed */ + return 1; + } + /* Need to temporarily map the area to make sure it is zeroed */ + ptr = memremap(ba, size, MEMREMAP_WB); + if (!ptr) { + pr_crit("memremap() of QMan private memory failed\n"); + return -ENOMEM; + } + memset(ptr, 0, size); + +#ifdef CONFIG_PPC + /* + * PPC doesn't appear to flush the cache on memunmap() but the + * cache must be flushed since QMan does non coherent accesses + * to this memory + */ + flush_dcache_range((unsigned long) ptr, (unsigned long) ptr+size); +#endif + memunmap(ptr); + qm_ccsr_out(offset, upper_32_bits(ba)); qm_ccsr_out(offset + REG_offset_BAR, lower_32_bits(ba)); qm_ccsr_out(offset + REG_offset_AR, PFDR_AR_EN | (exp - 1)); + return 0; } static void qm_set_pfdr_threshold(u32 th, u8 k) @@ -419,7 +456,7 @@ static int zero_priv_mem(phys_addr_t addr, size_t sz) { /* map as cacheable, non-guarded */ - void __iomem *tmpp = ioremap_prot(addr, sz, 0); + void __iomem *tmpp = ioremap_cache(addr, sz); if (!tmpp) return -ENOMEM; @@ -455,7 +492,7 @@ #endif -static unsigned int qm_get_fqid_maxcnt(void) +unsigned int qm_get_fqid_maxcnt(void) { return fqd_sz / 64; } @@ -571,12 +608,19 @@ int i, err; /* FQD memory */ - qm_set_memory(qm_memory_fqd, fqd_a, fqd_sz); - /* PFDR memory */ - qm_set_memory(qm_memory_pfdr, pfdr_a, pfdr_sz); - err = qm_init_pfdr(dev, 8, pfdr_sz / 64 - 8); - if (err) + err = qm_set_memory(qm_memory_fqd, fqd_a, fqd_sz); + if (err < 0) return err; + /* PFDR memory */ + err = qm_set_memory(qm_memory_pfdr, pfdr_a, pfdr_sz); + if (err < 0) + return err; + /* Only initialize PFDRs if the QMan was not initialized before */ + if (err == 0) { + err = qm_init_pfdr(dev, 8, pfdr_sz / 64 - 8); + if (err) + return err; + } /* thresholds */ qm_set_pfdr_threshold(512, 64); qm_set_sfdr_threshold(128); @@ -596,7 +640,7 @@ } #define LIO_CFG_LIODN_MASK 0x0fff0000 -void qman_liodn_fixup(u16 channel) +void __qman_liodn_fixup(u16 channel) { static int done; static u32 liodn_offset; @@ -693,6 +737,18 @@ } EXPORT_SYMBOL_GPL(qman_is_probed); +int qman_requires_cleanup(void) +{ + return __qman_requires_cleanup; +} + +void qman_done_cleanup(void) +{ + qman_enable_irqs(); + __qman_requires_cleanup = 0; +} + + static int fsl_qman_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; -- Gitblit v1.6.2