diff mbox series

[RFC,v1,148/256] cl8k: add reg/reg_access.h

Message ID 20210617160223.160998-149-viktor.barna@celeno.com
State New
Headers show
Series wireless: cl8k driver for Celeno IEEE 802.11ax devices | expand

Commit Message

Viktor Barna June 17, 2021, 4 p.m. UTC
From: Viktor Barna <viktor.barna@celeno.com>

(Part of the split. Please, take a look at the cover letter for more
details).

Signed-off-by: Viktor Barna <viktor.barna@celeno.com>
---
 .../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

--
2.30.0
diff mbox series

Patch

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 */