162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2020-2023 Intel Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __IVPU_HW_REG_IO_H__ 762306a36Sopenharmony_ci#define __IVPU_HW_REG_IO_H__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/bitfield.h> 1062306a36Sopenharmony_ci#include <linux/io.h> 1162306a36Sopenharmony_ci#include <linux/iopoll.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include "ivpu_drv.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define REG_POLL_SLEEP_US 50 1662306a36Sopenharmony_ci#define REG_IO_ERROR 0xffffffff 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define REGB_RD32(reg) ivpu_hw_reg_rd32(vdev, vdev->regb, (reg), #reg, __func__) 1962306a36Sopenharmony_ci#define REGB_RD32_SILENT(reg) readl(vdev->regb + (reg)) 2062306a36Sopenharmony_ci#define REGB_RD64(reg) ivpu_hw_reg_rd64(vdev, vdev->regb, (reg), #reg, __func__) 2162306a36Sopenharmony_ci#define REGB_WR32(reg, val) ivpu_hw_reg_wr32(vdev, vdev->regb, (reg), (val), #reg, __func__) 2262306a36Sopenharmony_ci#define REGB_WR64(reg, val) ivpu_hw_reg_wr64(vdev, vdev->regb, (reg), (val), #reg, __func__) 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define REGV_RD32(reg) ivpu_hw_reg_rd32(vdev, vdev->regv, (reg), #reg, __func__) 2562306a36Sopenharmony_ci#define REGV_RD32_SILENT(reg) readl(vdev->regv + (reg)) 2662306a36Sopenharmony_ci#define REGV_RD64(reg) ivpu_hw_reg_rd64(vdev, vdev->regv, (reg), #reg, __func__) 2762306a36Sopenharmony_ci#define REGV_WR32(reg, val) ivpu_hw_reg_wr32(vdev, vdev->regv, (reg), (val), #reg, __func__) 2862306a36Sopenharmony_ci#define REGV_WR64(reg, val) ivpu_hw_reg_wr64(vdev, vdev->regv, (reg), (val), #reg, __func__) 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define REGV_WR32I(reg, stride, index, val) \ 3162306a36Sopenharmony_ci ivpu_hw_reg_wr32_index(vdev, vdev->regv, (reg), (stride), (index), (val), #reg, __func__) 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define REG_FLD(REG, FLD) \ 3462306a36Sopenharmony_ci (REG##_##FLD##_MASK) 3562306a36Sopenharmony_ci#define REG_FLD_NUM(REG, FLD, num) \ 3662306a36Sopenharmony_ci FIELD_PREP(REG##_##FLD##_MASK, num) 3762306a36Sopenharmony_ci#define REG_GET_FLD(REG, FLD, val) \ 3862306a36Sopenharmony_ci FIELD_GET(REG##_##FLD##_MASK, val) 3962306a36Sopenharmony_ci#define REG_CLR_FLD(REG, FLD, val) \ 4062306a36Sopenharmony_ci ((val) & ~(REG##_##FLD##_MASK)) 4162306a36Sopenharmony_ci#define REG_SET_FLD(REG, FLD, val) \ 4262306a36Sopenharmony_ci ((val) | (REG##_##FLD##_MASK)) 4362306a36Sopenharmony_ci#define REG_SET_FLD_NUM(REG, FLD, num, val) \ 4462306a36Sopenharmony_ci (((val) & ~(REG##_##FLD##_MASK)) | FIELD_PREP(REG##_##FLD##_MASK, num)) 4562306a36Sopenharmony_ci#define REG_TEST_FLD(REG, FLD, val) \ 4662306a36Sopenharmony_ci ((REG##_##FLD##_MASK) == ((val) & (REG##_##FLD##_MASK))) 4762306a36Sopenharmony_ci#define REG_TEST_FLD_NUM(REG, FLD, num, val) \ 4862306a36Sopenharmony_ci ((num) == FIELD_GET(REG##_##FLD##_MASK, val)) 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define REGB_POLL(reg, var, cond, timeout_us) \ 5162306a36Sopenharmony_ci read_poll_timeout(REGB_RD32_SILENT, var, cond, REG_POLL_SLEEP_US, timeout_us, false, reg) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define REGV_POLL(reg, var, cond, timeout_us) \ 5462306a36Sopenharmony_ci read_poll_timeout(REGV_RD32_SILENT, var, cond, REG_POLL_SLEEP_US, timeout_us, false, reg) 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define REGB_POLL_FLD(reg, fld, val, timeout_us) \ 5762306a36Sopenharmony_ci({ \ 5862306a36Sopenharmony_ci u32 var; \ 5962306a36Sopenharmony_ci REGB_POLL(reg, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)), timeout_us); \ 6062306a36Sopenharmony_ci}) 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define REGV_POLL_FLD(reg, fld, val, timeout_us) \ 6362306a36Sopenharmony_ci({ \ 6462306a36Sopenharmony_ci u32 var; \ 6562306a36Sopenharmony_ci REGV_POLL(reg, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)), timeout_us); \ 6662306a36Sopenharmony_ci}) 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic inline u32 6962306a36Sopenharmony_ciivpu_hw_reg_rd32(struct ivpu_device *vdev, void __iomem *base, u32 reg, 7062306a36Sopenharmony_ci const char *name, const char *func) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci u32 val = readl(base + reg); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci ivpu_dbg(vdev, REG, "%s RD: %s (0x%08x) => 0x%08x\n", func, name, reg, val); 7562306a36Sopenharmony_ci return val; 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cistatic inline u64 7962306a36Sopenharmony_ciivpu_hw_reg_rd64(struct ivpu_device *vdev, void __iomem *base, u32 reg, 8062306a36Sopenharmony_ci const char *name, const char *func) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci u64 val = readq(base + reg); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci ivpu_dbg(vdev, REG, "%s RD: %s (0x%08x) => 0x%016llx\n", func, name, reg, val); 8562306a36Sopenharmony_ci return val; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic inline void 8962306a36Sopenharmony_ciivpu_hw_reg_wr32(struct ivpu_device *vdev, void __iomem *base, u32 reg, u32 val, 9062306a36Sopenharmony_ci const char *name, const char *func) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci ivpu_dbg(vdev, REG, "%s WR: %s (0x%08x) <= 0x%08x\n", func, name, reg, val); 9362306a36Sopenharmony_ci writel(val, base + reg); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic inline void 9762306a36Sopenharmony_ciivpu_hw_reg_wr64(struct ivpu_device *vdev, void __iomem *base, u32 reg, u64 val, 9862306a36Sopenharmony_ci const char *name, const char *func) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci ivpu_dbg(vdev, REG, "%s WR: %s (0x%08x) <= 0x%016llx\n", func, name, reg, val); 10162306a36Sopenharmony_ci writeq(val, base + reg); 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic inline void 10562306a36Sopenharmony_ciivpu_hw_reg_wr32_index(struct ivpu_device *vdev, void __iomem *base, u32 reg, 10662306a36Sopenharmony_ci u32 stride, u32 index, u32 val, const char *name, 10762306a36Sopenharmony_ci const char *func) 10862306a36Sopenharmony_ci{ 10962306a36Sopenharmony_ci reg += index * stride; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci ivpu_dbg(vdev, REG, "%s WR: %s_%d (0x%08x) <= 0x%08x\n", func, name, index, reg, val); 11262306a36Sopenharmony_ci writel(val, base + reg); 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci#endif /* __IVPU_HW_REG_IO_H__ */ 116