diff options
Diffstat (limited to 'drivers/soc/fsl/qbman/bman_ccsr.c')
-rw-r--r-- | drivers/soc/fsl/qbman/bman_ccsr.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/soc/fsl/qbman/bman_ccsr.c b/drivers/soc/fsl/qbman/bman_ccsr.c index 7c3cc968053c..cb24a08be084 100644 --- a/drivers/soc/fsl/qbman/bman_ccsr.c +++ b/drivers/soc/fsl/qbman/bman_ccsr.c @@ -97,17 +97,40 @@ static void bm_get_version(u16 *id, u8 *major, u8 *minor) /* signal transactions for FBPRs with higher priority */ #define FBPR_AR_RPRIO_HI BIT(30) -static void bm_set_memory(u64 ba, u32 size) +/* Track if probe has occurred and if cleanup is required */ +static int __bman_probed; +static int __bman_requires_cleanup; + + +static int bm_set_memory(u64 ba, u32 size) { + u32 bar, bare; u32 exp = ilog2(size); /* choke if size isn't within range */ DPAA_ASSERT(size >= 4096 && size <= 1024*1024*1024 && is_power_of_2(size)); /* choke if '[e]ba' has lower-alignment than 'size' */ DPAA_ASSERT(!(ba & (size - 1))); + + /* Check to see if BMan has already been initialized */ + bar = bm_ccsr_in(REG_FBPR_BAR); + if (bar) { + /* Maker sure ba == what was programmed) */ + bare = bm_ccsr_in(REG_FBPR_BARE); + if (bare != upper_32_bits(ba) || bar != lower_32_bits(ba)) { + pr_err("Attempted to reinitialize BMan with different BAR, got 0x%llx read BARE=0x%x BAR=0x%x\n", + ba, bare, bar); + return -ENOMEM; + } + pr_info("BMan BAR already configured\n"); + __bman_requires_cleanup = 1; + return 1; + } + bm_ccsr_out(REG_FBPR_BARE, upper_32_bits(ba)); bm_ccsr_out(REG_FBPR_BAR, lower_32_bits(ba)); bm_ccsr_out(REG_FBPR_AR, exp - 1); + return 0; } /* @@ -120,7 +143,6 @@ static void bm_set_memory(u64 ba, u32 size) */ static dma_addr_t fbpr_a; static size_t fbpr_sz; -static int __bman_probed; static int bman_fbpr(struct reserved_mem *rmem) { @@ -173,6 +195,16 @@ int bman_is_probed(void) } EXPORT_SYMBOL_GPL(bman_is_probed); +int bman_requires_cleanup(void) +{ + return __bman_requires_cleanup; +} + +void bman_done_cleanup(void) +{ + __bman_requires_cleanup = 0; +} + static int fsl_bman_probe(struct platform_device *pdev) { int ret, err_irq; |