From: Viktor Barna <viktor.barna@xxxxxxxxxx> (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna <viktor.barna@xxxxxxxxxx> --- .../net/wireless/celeno/cl8k/reg/reg_access.h | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/reg/reg_access.h diff --git a/drivers/net/wireless/celeno/cl8k/reg/reg_access.h b/drivers/net/wireless/celeno/cl8k/reg/reg_access.h new file mode 100644 index 000000000000..337f6f809d35 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/reg/reg_access.h @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright(c) 2019-2021, Celeno Communications Ltd. */ + +#ifndef CL_REG_ACCESS_H +#define CL_REG_ACCESS_H + +#include "hw.h" +#include "chip.h" +#include "ceva.h" +#include "fw/msg_tx.h" + +#define CL_REG_DBG(...) \ + do { \ + if (cl_hw->reg_dbg) \ + cl_dbg_verbose(__VA_ARGS__); \ + } while (0) + +#define CL_REG_DBG_CHIP(...) \ + do { \ + if (chip->reg_dbg) \ + cl_dbg_chip_verbose(__VA_ARGS__); \ + } while (0) + +#define XTENSA_PIF_BASE_ADDR 0x60000000 + +/* + * SHARED_RAM Address. + * Actually the PCI BAR4 window will be configured such as SHARED RAM + * is accessed with offset 0 (within the AHB Bridge main window) + */ +#define SHARED_RAM_START_ADDR 0x00000000 + +#define REG_MAC_HW_SMAC_OFFSET 0x80000 +#define REG_PHY_SMAC_OFFSET 0x100000 + +#define REG_MACDSP_API_BASE_ADDR 0x00400000 +#define REG_MAC_HW_BASE_ADDR 0x00600000 +#define REG_RIU_BASE_ADDR 0x00486000 +#define REG_RICU_BASE_ADDR 0x004B4000 + +#define APB_REGS_BASE_ADDR 0x007C0000 +#define I2C_REG_BASE_ADDR (APB_REGS_BASE_ADDR + 0x3000) +#define IPC_REG_BASE_ADDR (APB_REGS_BASE_ADDR + 0x4000) + +/* MACSYS_GCU_XT_CONTROL fields */ +#define SMAC_DEBUG_ENABLE BIT(21) +#define SMAC_BREAKPOINT BIT(20) +#define SMAC_OCD_HALT_ON_RESET BIT(19) +#define SMAC_RUN_STALL BIT(18) +#define SMAC_DRESET BIT(17) +#define SMAC_BRESET BIT(16) +#define UMAC_DEBUG_ENABLE BIT(13) +#define UMAC_BREAKPOINT BIT(11) +#define UMAC_OCD_HALT_ON_RESET BIT(11) +#define UMAC_RUN_STALL BIT(10) +#define UMAC_DRESET BIT(9) +#define UMAC_BRESET BIT(8) +#define LMAC_DEBUG_ENABLE BIT(5) +#define LMAC_BREAKPOINT BIT(4) +#define LMAC_OCD_HALT_ON_RESET BIT(3) +#define LMAC_RUN_STALL BIT(2) +#define LMAC_DRESET BIT(1) +#define LMAC_BRESET BIT(0) + +#define XMAC_BRESET \ + (LMAC_BRESET | SMAC_BRESET | UMAC_BRESET) +#define XMAC_DRESET \ + (LMAC_DRESET | SMAC_DRESET | UMAC_DRESET) +#define XMAC_RUN_STALL \ + (LMAC_RUN_STALL | SMAC_RUN_STALL | UMAC_RUN_STALL) +#define XMAC_OCD_HALT_ON_RESET \ + (LMAC_OCD_HALT_ON_RESET | SMAC_OCD_HALT_ON_RESET | UMAC_OCD_HALT_ON_RESET) +#define XMAC_DEBUG_ENABLE \ + (LMAC_DEBUG_ENABLE | SMAC_DEBUG_ENABLE | UMAC_DEBUG_ENABLE) + +/* Macro to read a platform register */ +#define REG_PL_RD(addr) le32_to_cpu(*(volatile __le32 *)(addr)) + +/* Macro to write a platform register */ +#define REG_PL_WR(addr, value) ((*(volatile __le32 *)(addr)) = cpu_to_le32(value)) + +#define CL_BAR_REG_READ(chip, reg) \ + le32_to_cpu((__force __le32)readl((chip)->pci_bar0_virt_addr + (reg))) + +#define CL_BAR_REG_WRITE(chip, reg, val) \ + writel((__force u32)cpu_to_le32(val), (chip)->pci_bar0_virt_addr + (reg)) + +static inline u32 get_actual_reg(struct cl_hw *cl_hw, u32 reg) +{ + if ((reg & 0x00ff0000) == REG_MAC_HW_BASE_ADDR) + return cl_hw->mac_hw_regs_offset + reg; + + if ((reg & 0x00f00000) == REG_MACDSP_API_BASE_ADDR) + return cl_hw->phy_regs_offset + reg; + + return reg; +} + +static inline u32 cl_reg_read(struct cl_hw *cl_hw, u32 reg) +{ + u32 actual_reg = get_actual_reg(cl_hw, reg); + u32 val = 0; + + if (actual_reg == (u32)(-1)) + return 0xff; + + val = REG_PL_RD(cl_hw->chip->pci_bar0_virt_addr + actual_reg); + CL_REG_DBG(cl_hw, "reg=0x%x, val=0x%x\n", actual_reg, val); + return val; +} + +static inline void cl_reg_write_direct(struct cl_hw *cl_hw, u32 reg, u32 val) +{ + u32 actual_reg = get_actual_reg(cl_hw, reg); + + if (actual_reg == (u32)(-1)) + return; + + CL_REG_DBG(cl_hw, "reg=0x%x, val=0x%x\n", actual_reg, val); + REG_PL_WR(cl_hw->chip->pci_bar0_virt_addr + actual_reg, val); +} + +#define BASE_ADDR(reg) ((ptrdiff_t)(reg) & 0x00fff000) + +static inline bool should_send_msg(struct cl_hw *cl_hw, u32 reg) +{ + /* + * Check in what cases we should send a message to the firmware, + * and in what cases we should write directly. + */ + if (!cl_hw->fw_active) + return false; + + return ((BASE_ADDR(reg) == REG_RIU_BASE_ADDR) || + (BASE_ADDR(reg) == REG_MAC_HW_BASE_ADDR)); +} + +static inline int cl_reg_write(struct cl_hw *cl_hw, u32 reg, u32 val) +{ + u32 actual_reg = get_actual_reg(cl_hw, reg); + int ret = 0; + + if (actual_reg == (u32)(-1)) + return -1; + + if (should_send_msg(cl_hw, reg)) { + CL_REG_DBG(cl_hw, "calling cl_msg_tx_reg_write: reg=0x%x, val=0x%x\n", + actual_reg, val); + cl_msg_tx_reg_write(cl_hw, (XTENSA_PIF_BASE_ADDR + actual_reg), val, U32_MAX); + } else { + CL_REG_DBG(cl_hw, "reg=0x%x, val=0x%x\n", actual_reg, val); + REG_PL_WR((cl_hw->chip->pci_bar0_virt_addr + actual_reg), val); + } + + return ret; +} + +static inline int cl_reg_write_mask(struct cl_hw *cl_hw, u32 reg, u32 val, u32 mask) +{ + u32 actual_reg = get_actual_reg(cl_hw, reg); + int ret = 0; + + if (actual_reg == (u32)(-1)) + return -1; + + if (should_send_msg(cl_hw, reg)) { + CL_REG_DBG(cl_hw, "calling cl_msg_tx_reg_write: reg=0x%x, val=0x%x, mask=0x%x\n", + actual_reg, val, mask); + cl_msg_tx_reg_write(cl_hw, (XTENSA_PIF_BASE_ADDR + actual_reg), val, mask); + } else { + u32 reg_rd = REG_PL_RD(cl_hw->chip->pci_bar0_virt_addr + actual_reg); + u32 val_write = ((reg_rd & ~mask) | (val & mask)); + + CL_REG_DBG(cl_hw, "reg=0x%x, mask=0x%x, val=0x%x\n", actual_reg, mask, val_write); + REG_PL_WR(cl_hw->chip->pci_bar0_virt_addr + actual_reg, val_write); + } + + return ret; +} + +static inline void cl_reg_write_chip(struct cl_chip *chip, u32 reg, u32 val) +{ + CL_REG_DBG_CHIP(chip, "reg=0x%x, val=0x%x\n", reg, val); + REG_PL_WR(chip->pci_bar0_virt_addr + reg, val); +} + +static inline u32 cl_reg_read_chip(struct cl_chip *chip, u32 reg) +{ + u32 val = 0; + + val = REG_PL_RD(chip->pci_bar0_virt_addr + reg); + + CL_REG_DBG_CHIP(chip, "reg=0x%x, val=0x%x\n", reg, val); + return val; +} + +#endif /* CL_REG_ACCESS_H */ -- 2.30.0 ________________________________ The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any retransmission, dissemination, copying or other use of, or taking of any action in reliance upon this information is prohibited. If you received this in error, please contact the sender and delete the material from any computer. Nothing contained herein shall be deemed as a representation, warranty or a commitment by Celeno. No warranties are expressed or implied, including, but not limited to, any implied warranties of non-infringement, merchantability and fitness for a particular purpose. ________________________________