// SPDX-License-Identifier: GPL-2.0-or-later /* * Support for Digigram AlpX PCI-e boards * * Copyright (c) 2024 Digigram Digital (info@digigram.com) */ #include "alpx_proc.h" #if defined(CONFIG_ALPX_WITH_PROC_LOG) int alpx_proc_log_dump(struct alpx_device *alpx_dev) { static unsigned char log_buffer[ALP_PROC_LOG_LENGTH]; unsigned char logged_word = 0; unsigned int addr = 0; //unsigned int idx = 0; struct alpx_device zero_base; zero_base.base = 0; dev_dbg( alpx_dev->dev,"%s(): uBlaze Log (%d):", __func__, ALP_PROC_LOG_LENGTH); for (addr = 0; addr < ALP_PROC_LOG_LENGTH ; addr += sizeof (u32)) { #if 0 dev_dbg( alpx_dev->dev,"%s() : log reg: %p + 0x%x => %p\n", __func__, alpx_dev->base, ALP_PROC_LOG_BASE + addr, ALPX_AREA(alpx_dev, ALP, PROC_LOG) + addr); #endif logged_word = readl(ALPX_AREA(alpx_dev, ALP, PROC_LOG) + addr); *(unsigned int*)&log_buffer[addr] = logged_word; #if 0 dev_dbg( alpx_dev->dev,"%s() : [0x%x] =>%d\n", __func__, ALP_PROC_LOG_BASE + addr, logged_word); #endif #if 0 for (idx = 0 ; idx < sizeof(u32) ; ++idx) { printk("%c",(unsigned char)logged_word); logged_word >>= 8; } #endif print_hex_dump_bytes(alpx_dev->dev,"LOG", DUMP_PREFIX_NONE, log_buffer, ALP_PROC_LOG_LENGTH); } return 0; } #endif int alpx_proc_cmd(struct alpx_device *alpx_dev, u32 command) { u32 status; u32 fails; int ret; /* Set status to detect proc register update */ writel(0xFFFFFFFF, ALPX_REG(alpx_dev, ALP, PROC, STATUS)); /* Post command */ writel(command, ALPX_REG(alpx_dev, ALP, PROC, COMMAND)); /* Poll status for first update */ ret = readl_poll_timeout(ALPX_REG(alpx_dev, ALP, PROC, STATUS), status, status != 0xFFFFFFFF, 10, 1000000); if (ret) { dev_err(alpx_dev->dev, "cmd 0x%08X timeout (status=%x)\n", command, status); alpx_proc_log_dump(alpx_dev); return ret; } /* Continue polling for end of processing */ ret = readl_poll_timeout(ALPX_REG(alpx_dev, ALP, PROC, STATUS), status, !(status & ALP_PROC_STATUS_PENDING), 10, 1000000); if (ret) { dev_err(alpx_dev->dev, "cmd 0x%08X timeout (status=%x)\n", command, status); alpx_proc_log_dump(alpx_dev); return ret; } mdelay(1); /* Command processing is done -> check results */ status = readl(ALPX_REG(alpx_dev, ALP, PROC, STATUS)); fails = readl(ALPX_REG(alpx_dev, ALP, PROC, FAILS)); dev_dbg(alpx_dev->dev,"cmd 0x%08X => status: 0x%x, fail:0x%x\n", command, status, fails); if ((status & ALP_PROC_STATUS_FAIL) && (fails != ALP_PROC_FAILS_FAIL_NONE)) { dev_err(alpx_dev->dev, "cmd 0x%08X failed (status=%x, fails=%x)\n", command, status, fails); alpx_proc_log_dump(alpx_dev); return -EIO; } alpx_proc_log_dump(alpx_dev); return 0; } int alpx_proc_probe(struct alpx_device *alpx_dev) { mutex_init(&alpx_dev->proc_mutex); return 0; } int alpx_proc_remove(struct alpx_device *alpx_dev) { mutex_destroy(&alpx_dev->proc_mutex); return 0; }